Handler Method : Jackson JSON

2024. 10. 9. 17:05Spring Framework/Web on Servlet Stack

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

'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글

@InitBinder  (0) 2024.10.09
Model  (0) 2024.10.09
Handler Method : ResponseEntity  (1) 2024.10.09
Handler Method : @ResponseBody  (0) 2024.10.09
Handler Method : HttpEntity  (0) 2024.10.09