Spring Framework/Web on Servlet Stack

Handler Method : Jackson JSON

헬로우월드 2024. 10. 9. 17:05

Spring MVC는 Jackson 라이브러리를 사용하여 JSON 형식의 데이터를 직렬화하고, Jackson의 Serialization Views 기능을 지원합니다. 이를 통해 객체의 모든 필드를 렌더링하지 않고, 특정 조건에 따라 일부 필드만 선택적으로 렌더링할 수 있습니다.

JSON 뷰 기능을 사용하는 방법

기본 개념

Spring에서 @ResponseBodyResponseEntity를 사용하여 JSON 데이터를 반환하는 경우, Jackson의 @JsonView 애노테이션을 이용하여 특정 필드만 직렬화할 수 있습니다. @JsonView는 객체의 특정 필드에 대해서만 특정 뷰를 활성화하여 직렬화할 수 있는 기능을 제공합니다.

예제 1: @JsonView를 이용한 직렬화

컨트롤러 예시

아래 예시에서는 UserControllerUser 객체를 JSON 형식으로 반환합니다. @JsonView를 사용하여 비밀번호 필드는 제외하고 username 필드만 포함된 JSON을 반환하는 방식입니다.

@RestController
public class UserController {

    @GetMapping("/user")
    @JsonView(User.WithoutPasswordView.class)
    public User getUser() {
        return new User("eric", "7!jd#h23");
    }
}

User 클래스

public class User {

    // 뷰 인터페이스 정의
    public interface WithoutPasswordView {};
    public interface WithPasswordView extends WithoutPasswordView {};

    private String username;
    private String password;

    // 기본 생성자
    public User() {}

    // 파라미터가 있는 생성자
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    // WithoutPasswordView 뷰를 사용할 때 포함될 필드
    @JsonView(WithoutPasswordView.class)
    public String getUsername() {
        return this.username;
    }

    // WithPasswordView 뷰를 사용할 때 포함될 필드
    @JsonView(WithPasswordView.class)
    public String getPassword() {
        return this.password;
    }
}

위 코드에서, @JsonView(User.WithoutPasswordView.class)getUsername() 메서드만 직렬화되도록 설정합니다. 즉, 비밀번호는 제외하고 사용자 이름만 포함된 JSON 응답이 반환됩니다.

예제 2: MappingJacksonValue를 사용한 동적 뷰 설정

만약 @JsonView 애노테이션을 사용하지 않고 동적으로 직렬화 뷰를 설정하고 싶다면, MappingJacksonValue 객체를 사용하여 뷰를 설정할 수 있습니다.

컨트롤러 예시

@RestController
public class UserController {

    @GetMapping("/user")
    public MappingJacksonValue getUser() {
        User user = new User("eric", "7!jd#h23");
        MappingJacksonValue value = new MappingJacksonValue(user);
        value.setSerializationView(User.WithoutPasswordView.class);
        return value;
    }
}

위 예시에서 MappingJacksonValue 객체를 사용하여 WithoutPasswordView를 직렬화 뷰로 설정합니다. 이렇게 하면 동적으로 특정 뷰를 선택하여 직렬화할 수 있습니다.

예제 3: 뷰 리졸루션을 사용하는 경우

컨트롤러가 뷰 리졸루션(View Resolution)을 사용하는 경우, 모델에 직렬화할 뷰 클래스를 추가하여 특정 뷰를 활성화할 수 있습니다.

컨트롤러 예시

@Controller
public class UserController {

    @GetMapping("/user")
    public String getUser(Model model) {
        model.addAttribute("user", new User("eric", "7!jd#h23"));
        model.addAttribute(JsonView.class.getName(), User.WithoutPasswordView.class);
        return "userView";
    }
}

위 코드에서는 modeluser 객체와 함께 JsonView.class.getName()을 키로 사용하여 직렬화할 뷰 클래스를 추가합니다. 이렇게 하면 지정된 뷰(WithoutPasswordView)에 따라 필드가 직렬화됩니다.

JSON 뷰 활용 방식 요약

  • @JsonView 애노테이션: 메서드에 직접 뷰 클래스를 적용하여 특정 필드만 직렬화할 수 있습니다.
  • MappingJacksonValue: 동적으로 뷰를 설정하고, @JsonView 없이도 직렬화할 필드를 선택할 수 있습니다.
  • 뷰 리졸루션(View Resolution): Spring MVC의 뷰 리졸루션을 사용할 때는 모델에 직렬화할 뷰 클래스를 추가하여 처리할 수 있습니다.

요약

Jackson의 @JsonView 기능을 통해 객체의 필드를 선택적으로 직렬화할 수 있으며, Spring MVC는 이를 쉽게 사용할 수 있는 방법을 제공합니다.

  • @JsonView 애노테이션을 사용하여 뷰를 설정하면, 메서드 수준에서 특정 필드만 직렬화할 수 있습니다.
  • MappingJacksonValue를 사용하면 동적으로 뷰를 설정할 수 있습니다.
  • 뷰 리졸루션과 함께 사용하면, 뷰와 직렬화를 연계하여 처리할 수 있습니다.

샘플 코드 (모든 예시 종합)

@RestController
public class UserController {

    // @JsonView 사용
    @GetMapping("/user")
    @JsonView(User.WithoutPasswordView.class)
    public User getUser() {
        return new User("eric", "7!jd#h23");
    }

    // MappingJacksonValue 사용
    @GetMapping("/dynamicUser")
    public MappingJacksonValue getUserDynamicView() {
        User user = new User("eric", "7!jd#h23");
        MappingJacksonValue value = new MappingJacksonValue(user);
        value.setSerializationView(User.WithoutPasswordView.class);
        return value;
    }

    // 뷰 리졸루션 사용
    @GetMapping("/userView")
    public String getUserView(Model model) {
        model.addAttribute("user", new User("eric", "7!jd#h23"));
        model.addAttribute(JsonView.class.getName(), User.WithoutPasswordView.class);
        return "userView";
    }
}

public class User {

    public interface WithoutPasswordView {};
    public interface WithPasswordView extends WithoutPasswordView {};

    private String username;
    private String password;

    public User() {}

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @JsonView(WithoutPasswordView.class)
    public String getUsername() {
        return this.username;
    }

    @JsonView(WithPasswordView.class)
    public String getPassword() {
        return this.password;
    }
}

이 코드를 통해 다양한 방법으로 객체를 직렬화할 수 있으며, 상황에 따라 뷰를 조절하여 필요한 정보만 JSON으로 반환할 수 있습니다.

참고 : https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/jackson.html