본문 바로가기
코딩 공부/web & Java

[Spring] Response Customizing

by 현장 2023. 11. 20.

Response Customizing

RestAPI에서 Response로 Bean을 반환 할때, 구조는 Bean의 모든 변수를 반환하게 됩니다. 하지만 특정 상황에서 이와 같이 정확하게 모든 Bean의 모든 값을 반환하고 싶지 않은 경우 커스터마이징을 사용합니다.

 

🏷️ 정적 필터링

정적 필터링은 필터를 적용하면 해당 Bean에 대한 모든 응답에 동일하게 필터링이 됩니다.

@JsonIgnoreProperties("field1") // 정적 필터링 방법2 -> 여러게 필터링시 {v1, v2} 형식
public class SomeBean {
    private String field1;
    @JsonIgnore // 정적 필터링 방법 1 -> 필드 이름 변경시 따로 변경하지 않아도됨
    private String field2;
    private String field3;

    public SomeBean(String field1, String field2, String field3) {
        this.field1 = field1;
        this.field2 = field2;
        this.field3 = field3;
    }

    // getter와 toString 생략
}

 

먼저 정적 필터링으로 2가지 방법을 소개합니다.

✅ @JsonIgnore

첫번째로 @JsonIgnore입니다. 이 어노테이션을 필터링 하고 싶은 필드위에 선언을 하게 되면 해당 필터가 응답으로 출력되지 않습니다. 또한 이 방법을 사용하면 필드 이름 변경시 따로 변경을 하지 않아도 됩니다.

 

위 코드에서 방법 1번만 사용했을 경우 아래와 같은 출력이 나오게 됩니다.

{
	"field1": "value1"
	"field3": "value3"
}

✅ @JsonIgnoreProperties

두 번째로는 @JsonIgnoreProperties입니다. 이 어노테이션은 해당하는 Bean위에 선언을 하며 필터링할 필드의 명을 매개 변수로 입력해 주어야 합니다. 2개 이상의 필드를 필터링할 경우 {"field1", "field2"}와 같이 {} 안에 필드명을 입력하여 사용해야 합니다.

 

위의 코드에서 방법 2번만 사용했을 경우 아래와 같은 출력이 나오게 됩니다.

{
    "field2": "value2"
    "field3": "value3"
}

🏷️ 동적 필터링

같은 Bean이라도 RestAPI에 따라서 다른 속성을 반환하고 싶을 경우 사용합니다.

@GetMapping("/filtering-dynamic")
    public MappingJacksonValue filteringDynamic() {
        SomeBean2 someBean2 = new SomeBean2("value1", "value2", "value3");

        // 동적 필터
        MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(someBean2);
        PropertyFilter filter
                = SimpleBeanPropertyFilter.filterOutAllExcept("field1", "field3");
        FilterProvider filters
                = new SimpleFilterProvider().addFilter("SomeBean2Filter", filter);
        mappingJacksonValue.setFilters(filters);

        return mappingJacksonValue;
    }

    @GetMapping("/filtering-dynamic-list")
    public MappingJacksonValue filteringDynamicList() {
        List<SomeBean2> list = Arrays.asList(
                new SomeBean2("value1", "value2", "value3"),
                new SomeBean2("value4", "value5", "value6"),
                new SomeBean2("value7", "value8", "value9")
        );

        MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(list);
        PropertyFilter filter
                = SimpleBeanPropertyFilter.filterOutAllExcept("field2", "field3");
        FilterProvider filters
                = new SimpleFilterProvider().addFilter("SomeBean2Filter", filter);
        mappingJacksonValue.setFilters(filters);

        return mappingJacksonValue;
    }

MappingJacksonValue

스프링 프레임워크에서 제공하는 클래스로, 특정 JSON 값을 필터링하거나 래핑하는 데 사용됩니다. 주로 컨트롤러에서 특정 응답을 JSON으로 반환할 때 사용됩니다.

MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(someBean2);

PropertyFilter

Jackson 라이브러리에서 사용되는 인터페이스로, Java 객체의 속성을 JSON으로 변환할 때 어떤 속성을 포함하거나 제외할지를 동적으로 제어하는 데 사용됩니다.

 

PropertyFilter를 구현하려면 filter 메서드를 구현해야 합니다. 이 메서드는 각각의 속성에 대해 호출되고, 속성을 포함할지 제외할지 여부를 결정합니다.

PropertyFilter filter
        = SimpleBeanPropertyFilter.filterOutAllExcept("field1", "field3");
        // "field1", "field3"만 출력되도록 필터링합니다.
Jackson
Java 객체를 JSON으로 변환하거나, JSON을 Java 객체로 변환하는 데 사용되는 강력하고 널리 사용되는 라이브러리 중 하나입니다.

 

FilterProvider

Jackson의 Java객체를 JSON으로 변환할 때 일부 속성을 제외하거나 포함시키는 기능을 지원합니다. 특정 필터를 사용하여 변환되는 속성을 동적으로 제어할 수 있습니다.

FilterProvider filters
        = new SimpleFilterProvider().addFilter("SomeBean2Filter", filter);

 출력

// 단일 Bean 경우
{
    "field1": "value1",
    "field3": "value3"
}

// list 경우
[
    {
        "field1": "value1",
        "field3": "value3"
    },
    {
        "field1": "value4",
        "field3": "value6"
    },
    {
        "field1": "value7",
        "field3": "value9"
    }
]