반응형

gson 을 사용할 떄 json 구조에 맞춰서 fromJson 메소드를 호출하면 자동으로 파싱을 해주지만,

종종 커스텀을 해서 파싱을 해야 할떄가 있다.

 

1. 해야하는 순간은 해당 데이터가 모두 동일한 포맷으로 파싱이 되어야 한다든지,

EX) 공백 "" 스트링이 있으면 항상 null 로 치환, 또는 날짜가 포함된 경우 동일한 포맷으로 파싱해야 하는 경우.

2. 일반적인 방식으로 파싱이 어려운 경우

EX) json 객체의 키값이 가변적인 경우여서 객체명으로 파싱이 불가능할 경우

{ 
 "1234": {
	"name" : "cat"
 },
 "5594": {
 	"name": "dog" 
 }
}

EX) 같은 json 키 이지만 값에 value 에 따라 파싱되는 객체 구조가 다를 경우

 

 

여기서 registerTypeAdapter 에 넣는 class 에 따라 해당 클래스가 있는 json 이 gson 으로 파싱될떄 deserializer 가 호출된다.

String.class 를 넣으면 파싱되는 데이터타입중에 String 인 데이터는 모두 deserialize 를 호출하게 된다.

CustomDeserializer 클래스

public class CustomDeserializer implements JsonDeserializer<ReturnVo> {

	/**
	 * JsonElement json parameter 은 parsing 하려는 전체 json 데이터
	 */
	@Override
	public ReturnVo deserialize(JsonElement json, java.lang.reflect.Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
	
		ReturnVo returnVo = new ReturnVo();
      	JsonObject jsonObject = json.getAsJsonObject();
        /**
          파싱 
        */
    return returnVo;
	}
}

사용 예시

GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(ReturnVo.class, new CustomDeserializer()); 
Gson gson = builder.create();
ReturnVo response = gson.fromJson(jsonStr, ReturnVo.class); /** fromJson 호출시 CustomDeserializer 가 호출됨*/
return response;

 

 

참고문헌

> https://stackoverflow.com/questions/28319473/gson-same-field-name-different-types [Same field name, different types] 

반응형
반응형

java 에서 파싱을 해주는 라이브러리가 있는데 대표적인 라이브러리고 gson 과 jackson 있다.

gson 을 사용시 기본적으로 new Gson().toJson() 및 fromJson() 으로 기본적인 파싱이 되지만, 종종 커스텀이 필요한 경우가 있다,

이런 경우 Desrializer 및 Serializer 기능이 필요하다.

1. Custom Serialization

Serialization 은 toJson 할 경우 필요하다. 자바 객체를 Json 으로 변환 시 필요하다.

예시

Serialization 생성

public class BooleanSerializer implements JsonSerializer<Boolean> {

    public JsonElement serialize(Boolean aBoolean, Type type,
        JsonSerializationContext jsonSerializationContext) 
    {
        if(aBoolean){
           return new JsonPrimitive(1);
        }
        return new JsonPrimitive(0);
    }
}

사용

    public static void main(String[] args) throws Exception 
    {
        Employee emp = new Employee(1, "Lokesh", "Gupta", "howtodoinjava@gmail.com", true);

        Gson gson = new GsonBuilder()
                .registerTypeAdapter(Boolean.class, new BooleanSerializer())
                .setPrettyPrinting()
                .create();

        String json = gson.toJson(emp);

        System.out.println(json);
    }

결과물

{
  "id": 1,
  "firstName": "Lokesh",
  "lastName": "Gupta",
  "email": "howtodoinjava@gmail.com",
  "active": 1
}

다음과 같이 boolean 이 1또는 0 으로 Json 변환시 사용하려면 다음과 같이 사용하면 된다.

반대로 1또는 0을 true 또는 false 로 변환하려면 JsonDeserializer 을 반대로 implements 를 하면 된다.

이 떄 registerTypeAdapter 메소드는 빌더 타입이라 추가로 클래스를 붙이고 싶은 경우가 있으면 추가하면 된다.

날짜를 gson으로 Serialize 하기

또 사용해야 하는 이유는 날짜 Date 클래스를 gson 으로 Json String 을 만들시

Aug 31, 2020 10:26:17 처럼 날짜가 표시된다. 하지만 2020-08-31 10:26:17 이렇게 변환되기를 바랄것이다.

JsonSerializer<Date> ser = new JsonSerializer<Date>() {
    @Override
    public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext
                context) {
        return src == null ? null : new JsonPrimitive(src.getTime());
    }
};

JsonDeserializer<Date> deser = new JsonDeserializer<Date>() {
    @Override
    public Date deserialize(JsonElement json, Type typeOfT,
                JsonDeserializationContext context) throws JsonParseException {
        return json == null ? null : new Date(json.getAsLong());
    }
};

Gson gson = new GsonBuilder()
                .registerTypeAdapter(Date.class, ser)
                .registerTypeAdapter(Date.class, deser)
                .create();

다음과 같이 익명클래스 로 객체 선언 후 사용 가능 하다.

 

2. Custom Deserialization

반대로 json String 을 객체로 변환시 아래와 같이 사용하면 된다.

json 문자열을 객체로 파싱할때 빈 문자열을 null 로 치환

public class EmptyToNullStringDeserializerGson implements JsonDeserializer<String> {

	@Override
	public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
		String nullCheckString = json.getAsJsonPrimitive().getAsString();
		return "".equals(nullCheckString) ? null : nullCheckString;  
	}

}

사용법

GsonBuilder gb = new GsonBuilder();
gb.registerTypeAdapter(String.class, new EmptyToNullStringDeserializerGson());
Gson gson = gb.create();

클래스 response =  gson.fromJson(jsonStr, 클래스명.class);

 

 

참고문헌

https://riptutorial.com/android/example/15339/custom-json-deserializer-using-gson
https://futurestud.io/tutorials/gson-advanced-custom-deserialization-basics
https://howtodoinjava.com/gson/custom-serialization-deserialization/

반응형

+ Recent posts