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

자바 Jackson @JsonView 어노테이션 완벽 가이드: 직렬화 프로퍼티 동적 제어 방법

@JsonView 어노테이션은 직렬화(Serialization)와 역직렬화(Deserialization) 과정에서 특정 프로퍼티를 동적으로 포함하거나 제외할 수 있게 해주는 강력한 기능입니다. 예를 들어, 외부에 공개할 데이터와 내부적으로만 사용할 데이터를 구분해야 할 때 매우 유용합니다.

이 어노테이션을 실제로 활용하려면 ObjectMapper 클래스를 설정한 후, writerWithView() 메서드를 사용하여 자바 객체를 JSON으로 변환할 때 적용할 뷰(View) 타입을 지정해야 합니다.

문법(Syntax)

@Target(value={ANNOTATION_TYPE,METHOD,FIELD})
@Retention(value=RUNTIME)
public @interface JsonView

예제(Example)

아래 예제에서는 Views.PublicViews.Internal 두 개의 뷰를 정의하고, 각 뷰에 따라 다른 프로퍼티가 JSON으로 출력되는 것을 확인할 수 있습니다.

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.core.JsonProcessingException;

public class JsonViewAnnotationTest {
    public static void main(String args[]) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writerWithView(Views.Public.class).writeValueAsString(new Person());
        String jsonStringInternal = objectMapper.writerWithView(Views.Internal.class).writeValueAsString(new Person());
        System.out.println(jsonString);
        System.out.println(jsonStringInternal);
    }
}

// Person 클래스
class Person {
    @JsonView(Views.Public.class)
    public long personId = 115;

    @JsonView(Views.Public.class)
    public String personName = "Raja Ramesh";

    @JsonView(Views.Internal.class)
    public String gender = "male";

    @Override
    public String toString() {
        return "Person{" +
                "personId=" + personId +
                ", personName='" + personName + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

// 뷰 정의
class Views {
    static class Public {}
    static class Internal extends Public {}
}

출력 결과(Output)

{"personId":115,"personName":"Raja Ramesh"}
{"personId":115,"personName":"Raja Ramesh","gender":"male"}

동작 원리

출력 결과를 보면 Views.Public 뷰를 적용했을 때는 personIdpersonName만 포함되고, gender 필드는 제외된 것을 확인할 수 있습니다. 반면 Views.Internal 뷰를 적용하면 세 필드가 모두 출력됩니다.

그 이유는 Views.InternalViews.Public을 상속(extends)하기 때문입니다. Jackson의 뷰는 계층 구조를 가지며, 하위 뷰를 적용하면 상위 뷰에 속한 프로퍼티까지 모두 포함됩니다. 즉, Internal 뷰는 Public 뷰의 모든 필드에 자신의 필드를 추가한 형태로 동작합니다.

이러한 특성을 활용하면 REST API에서 사용자 권한별로 노출하는 데이터를 다르게 설정하는 등, 하나의 모델 클래스로 다양한 응답 형태를 유연하게 처리할 수 있습니다.