REST API 동적 필터링 구현

Soo·2024년 3월 28일

정적 필터링에서는 @JsonIgnore를 붙인 필드는 모든 REST API에서 필터링이 되었습니다.

하지만, 같은 빈이라도 REST API에 따라 다른 속성을 반환하고 싶을 수도 있을겁니다.

동적 필터링을 사용하면 REST API마나 다른 속성을 반환할 수 있습니다.

바로 알아보겠습니다.

예를들어, filteringfiltering-list라는 두 REST API가 있을 때 filtering으로는 field1field3를 응답을 받고싶습니다.

하지만, filtering-list로는 field2field3를 응답받고 싶습니다.

같은 빈이라도 REST API에 따라 응답이 달라지는 것이죠

사용법

  • 필터링하고싶은 Controller에서 MappingJacksonValue를 사용해서 Bean을 매핑
  • SimpleBeanPropertyFilter를 사용해서 filter를 생성
  • filtering 하고싶은 Bean에 @JsonFilter를 사용해서 이름 지정
  • SimpleFilterProvider.addFilter()에 filtering하고 싶은 Bean의 @JsonFilter에 작성했던 이름과, 앞에서 생성한 filter를 파라미터로 넘김
  • mappingJacksonValue.setFilters()에 filters를 파라미터로 넘겨서 필터링환경 세팅
  • mappginJacksonValue 반환

SomeBean

  • @JsonFilter("SomeBeanFilter")
package study.rest.webservices.restfulwebservices.filtering;

import com.fasterxml.jackson.annotation.JsonFilter;

//@JsonIgnoreProperties("field1")
@JsonFilter("SomeBeanFilter")
public class SomeBean {
    private String field1;

    private String field2;
//    @JsonIgnore
    private String field3;

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

    public String getField1() {
        return field1;
    }

    public String getField2() {
        return field2;
    }

    public String getField3() {
        return field3;
    }

    @Override
    public String toString() {
        return "SomeBean{" +
                "field1='" + field1 + '\'' +
                ", field2='" + field2 + '\'' +
                ", field3='" + field3 + '\'' +
                '}';
    }
}

FilteringController

  • filtering() - field2를 제외
  • filteringList()- field3를 제외
package study.rest.webservices.restfulwebservices.filtering;

import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;

@RestController
public class FilteringController {

    @GetMapping("/filtering")
    public MappingJacksonValue filtering() {
        SomeBean someBean = new SomeBean("value1", "value2", "value3");

        //필터링
        return getMappingJacksonValue(new MappingJacksonValue(someBean), "field1", "field3");
    }

    @GetMapping("/filtering-list")
    public MappingJacksonValue filteringList() {
        List<SomeBean> someBeans = Arrays.asList(new SomeBean("value1", "value2", "value3"),
                new SomeBean("value4", "value5", "value6"));

        //필터링
        return getMappingJacksonValue(new MappingJacksonValue(someBeans), "field2", "field3");
    }

    private MappingJacksonValue getMappingJacksonValue(MappingJacksonValue bean, String... fields) {
        MappingJacksonValue mappingJacksonValue = bean;
        final String FILTER_ID = "SomeBeanFilter";
        SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.filterOutAllExcept(fields);
        FilterProvider filters = new SimpleFilterProvider().addFilter(FILTER_ID, filter);
        mappingJacksonValue.setFilters(filters);
        return mappingJacksonValue;
    }
}

filtering() 실행 결과

filteringList() 실행 결과

0개의 댓글