Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Gson에서 @JsonAdapter 어노테이션으로 커스텀 JsonAdapter(TypeAdapter) 구현하는 방법

Gson 라이브러리에서 @JsonAdapter 어노테이션은 필드 또는 클래스 수준에 적용하여 해당 타입을 직렬화·역직렬화할 때 사용할 어댑터를 지정하는 데 활용됩니다. TypeAdapter 클래스는 Java 객체를 JSON으로 변환하거나 그 반대로 변환하는 역할을 담당합니다.

기본적으로 Gson은 내장(built-in) 타입 어댑터를 사용해 애플리케이션 클래스를 JSON으로 변환하지만, 개발자가 직접 커스텀 타입 어댑터를 제공하면 이 기본 동작을 손쉽게 재정의(override)할 수 있습니다. 예를 들어 특정 필드를 객체 형태로 감싸서 출력하거나, 날짜·숫자 포맷을 원하는 대로 바꾸고 싶을 때 유용합니다.

@JsonAdapter 어노테이션 문법

@Retention(value=RUNTIME)
@Target(value={TYPE,FIELD})
public @interface JsonAdapter

위 정의에서 볼 수 있듯이 @JsonAdapterTYPE(클래스)FIELD(필드) 두 곳에 모두 적용 가능하며, 런타임 시점에 Gson이 이를 참조합니다.

예제 코드

아래 예제는 Customer 클래스의 customerId 필드에 커스텀 어댑터를 적용하여, 숫자 값을 JSON 객체 형태로 출력하는 방법을 보여줍니다.

import java.io.IOException;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

public class JsonAdapterTest {
    public static void main(String[] args) {
        Gson gson = new Gson();
        System.out.println(gson.toJson(new Customer()));
    }
}

// Customer 클래스
class Customer {
    @JsonAdapter(CustomJsonAdapter.class)
    Integer customerId = 101;
}

// CustomJsonAdapter 클래스
class CustomJsonAdapter extends TypeAdapter<Integer> {
    // JSON을 읽어 Java 객체로 변환 (역직렬화)
    @Override
    public Integer read(JsonReader jreader) throws IOException {
        return null;
    }

    // Java 객체를 JSON으로 변환 (직렬화)
    @Override
    public void write(JsonWriter jwriter, Integer customerId) throws IOException {
        jwriter.beginObject();
        jwriter.name("customerId");
        jwriter.value(String.valueOf(customerId));
        jwriter.endObject();
    }
}

코드 설명

  • @JsonAdapter(CustomJsonAdapter.class): customerId 필드가 직렬화될 때 Gson의 기본 어댑터 대신 CustomJsonAdapter가 사용되도록 지정합니다.
  • write(): Java 객체(Integer)를 JSON으로 변환하는 메서드로, 여기서는 값을 문자열로 변환한 뒤 중첩된 객체 형태로 감싸서 출력합니다.
  • read(): JSON을 Java 객체로 변환하는 메서드로, 이 예제에서는 단순화를 위해 null을 반환합니다.

실행 결과

{"customerId":{"customerId":"101"}}

출력 결과를 보면 일반적인 숫자 값("customerId":101) 대신, 커스텀 어댑터의 write() 로직에 따라 값이 문자열 "101"로 변환되고 객체로 한 번 더 감싸진 것을 확인할 수 있습니다. 이처럼 TypeAdapter를 상속받아 read()write()만 구현하면, Gson의 직렬화·역직렬화 과정을 완전히 제어할 수 있습니다.