[Gson] TypeAdapter

개발/Java 2016. 6. 10. 23:08
반응형

기존까지 Json Parser는 Jackson을 사용하고 있었는데,

어딘가에서 Gson이 가장 퍼포먼스가 좋다는 이야기를 듣고, 작년부터 Gson을 도입하여 사용하기로 하였다.

 

근데.. 엄청난 문제가 하나 있었다.

Number Type의 경우 toJson이나 fromJson메소드를 사용 시에, 무조건 double형태로 내부적으로 변환을 해서 주는 것이었다.

 

물론.. Integer라던지, Long이라던지 제대로 명시를 해서 변환을 요청하면 제대로 바꿔준다.  

하지만, Map<String, Object> 형태를 사용하여, 변환을 요청하는 경우 위와 같은 문제가 발생. 

 

성능을 높이기 위해 모든 Number Type을 double로 바꿔주는 것인가...  

자세한 이유는 만든사람만 알겠지;;

 

처음에는 일일히 double로 받아서, int로 변환해서 사용을 하였었는데..

찾아보니 역시나 간단하게 해결할 수 있는 방법이 있었다.

 

gson객체에 registerTypeAdapter라는 설정 관련 메소드가 있었고,

이것을 통해, Double로 들어오는 것들을 값의 범위를 계산하여 

Integer범위보다 크면 Long으로.. 아니면 Integer로 변경하도록 구현해보았다.

 

참고로, toJson과 fromJson을 사용 시 구현해야 하는 인터페이스가 다르다.

 

toJson : JsonDeserializer<T>

fromJson : JsonSerializer<T>

 

현재 클라이언트에서 받는 객체는 Pojo로 타입이 확실하게 명시되어 있고,

Response Data의 경우 Map으로 받고 있어서, toJson(obj, HashMap.class)을 할 때,  

무조건 .0이 붙어서 나오는 문제가 있으니 JsonDeserializer를 구현해서 쓰도록 결정하였다.

 

 

@Override
public HashMap<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        Map<String, Object> map = Maps.newHashMap();
        JsonObject jsonObject = json.getAsJsonObject();
        for(Entry<String, JsonElement> entry : jsonObject.entrySet()) {
            JsonElement element = entry.getValue();
            if(element instanceof JsonPrimitive && element.getAsJsonPrimitive().isNumber()) {
                Number nValue = CommonUtils.getRemoveDot(element.getAsDouble());
                map.put(entry.getKey(), nValue);
                
            } else {
                map.put(entry.getKey(), context.deserialize(element, Object.class));
            }
        }
        return (HashMap<String, Object>) map;
}

서비스에도 적용되어 있는 상태인데, 특별한 문제는 없었다.

반응형
,