hoony's web study

728x90
반응형

1. 개요

 

전일, 작업을 하던중 제가 받는 API가 데이터를 객체로 넘겨주다가,

 

빈 데이터는 빈배열로 넘겨서 json 을 unmarshal 하는 부분에서 에러가나며

 

모델이 제 역할을 못하는 불상사가 발생하였습니다.

 

2. reflect

 

위와같은 문제를 해결하기 위해 reflect 를 이용하였습니다.

 

[resonse json example]

 

{
  "profiles": [
    {
      "name": "lsh",
      "desc": "this man is awesome",
      "age": 28,
      "gender": "male",
      "fav": {
        "song": "달팽이",
        "game": "Apex Legends",
        "actor": "김우빈"
      }
    },
    {
      "name": "ljh",
      "desc": "the man who loves IT",
      "gender": "male",
      "fav": {
        "song": "순정",
        "game": "Clash Royal",
        "actress": "김희선"
      }
    },
    {
      "name": "kjh",
      "desc": "he's cool",
      "age": 27,
      "gender": "male",
      "fav": []
    }
  ]
}

 

위와같이, 빈 데이터를 갑자기 빈배열로 넘기는 경우가 있었습니다.

 

이에따라, 저는 reflect를 이용하여 문제를 해결하였는데, 아래에서 확인해보겠습니다.

 

[샘플 코드]

 

type apiResult struct {
   Profiles []struct {
      Name   string      `json:"name"`
      Desc   string      `json:"desc,omitempty"`
      Age    int         `json:"age,omitempty"`
      Gender string      `json:"gender"`
      Fav    interface{} `json:"fav"`
   } `json:"profiles"`
}

type favDetail struct {
   Song    string `json:"song,omitempty"`
   Game    string `json:"game,omitempty"`
   Actor   string `json:"actor,omitempty"`
   Actress string `json:"actress,omitempty"`
}

 

위와같이, 타입이 일정치 않은 fav 컬럼에 대해서는 interface{} 로 선언해주도록 합니다.

 

func errCheck(e error) {
   if e != nil {
      panic(e)
   }
}

func main() {
   jsonData, err := ioutil.ReadFile("./examplejson.json")
   errCheck(err)

   var resultVO apiResult

   err = json.Unmarshal([]byte(string(jsonData)), &resultVO)
   errCheck(err)

   for _, v := range resultVO.Profiles {
      fmt.Printf("이름 : %v\n", v.Name)
      fmt.Printf("나이 : %v\n", v.Age)
      fmt.Printf("추가설명 : %v\n", v.Desc)

      favReflect := reflect.TypeOf(v.Fav)
      fmt.Println(favReflect)

      if favReflect.String() == "map[string]interface {}" {
         //해당 인터페이스를 다시 json 으로 변환 후, 선언한 타입에 Map
         var favStruct favDetail
         favJson, _ := json.Marshal(v.Fav)

         err = json.Unmarshal([]byte(string(favJson)), &favStruct)
         errCheck(err)

         fmt.Printf("[Favorite] -노래 : %v\n", favStruct.Song)
         fmt.Printf("[Favorite] -게임 : %v\n", favStruct.Game)
         fmt.Printf("[Favorite] -배우(남) : %v\n", favStruct.Actor)
         fmt.Printf("[Favorite] -배우(여) : %v\n", favStruct.Actress)
      }

   }

}

 

위의 코드를 확인해보시면 아래와 같이, Type이 체크되는것을 보실 수 있습니다.

 

[ Console ]

 

이름 : lsh
나이 : 28                      
추가설명 : this man is awesome 
map[string]interface {}        
[Favorite] -노래 : 달팽이      
[Favorite] -게임 : Apex Legends
[Favorite] -배우(남) : 김우빈  
[Favorite] -배우(여) :         
이름 : ljh                     
나이 : 0                       
추가설명 : the man who loves IT
map[string]interface {}        
[Favorite] -노래 : 순정        
[Favorite] -게임 : Clash Royal 
[Favorite] -배우(남) :         
[Favorite] -배우(여) : 김희선  
이름 : kjh                     
나이 : 27                      
추가설명 : he's cool           
[]interface {}  

728x90

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading