잭슨 연속화 시 속성을 동적으로 무시하는 방법
여러 개의 엔티티가 있습니다.@ManyToOne
협회REST API를 노출하기 위해 spring-boot을 사용하고 있습니다.현재 저는 연관성을 포함한 전체 엔티티의 JSON 응답을 반환하는 여러 REST API를 보유하고 있습니다.
그러나 모든 REST API에서 모든 관련 개체를 직렬화하고 싶지는 않습니다.
예를들면
- API-1은 상위 + 연결A 개체를 반환해야 합니다.
- API-2는 상위 + 연결 A + 연결 B 개체를 반환해야 합니다.
- API-3은 상위 + 연결 B + 연결 C + 연결을 반환해야 합니다.d
그래서 제 직렬화 과정에서 API-1에 대한 연관성 A를 제외한 모든 연관성을 무시하고 싶습니다.
API-2의 경우 A와 B를 제외한 다른 연관성을 무시하고 싶습니다.
잭슨 직렬화 중에 이러한 속성을 동적으로 무시하려면 어떻게 해야 합니까?
참고: 각 API에 대해 동일한 클래스를 사용합니다. 각 API에 대해 DTO를 생성하는 데는 관심이 없습니다.
어떤 제안이든 대단히 감사합니다.
저는 잭슨에서 동적 필터링을 수행하기 위한 세 가지 접근법을 만들었습니다.그 중 하나는 당신의 요구에 맞아야 합니다.
사용.@JsonView
다음을 사용할 수 있습니다.
public class Views {
interface Simple { }
interface Detailed extends Simple { }
}
public class Foo {
@JsonView(Views.Simple.class)
private String name;
@JsonView(Views.Detailed.class)
private String details;
// Getters and setters
}
@RequestMapping("/foo")
@JsonView(Views.Detailed.class)
public Foo getFoo() {
Foo foo = new Foo();
return foo;
}
또는 를 사용하여 보기를 동적으로 설정할 수 있습니다.
@RequestMapping("/foo")
public MappingJacksonValue getFoo() {
Foo foo = new Foo();
MappingJacksonValue result = new MappingJacksonValue(foo);
result.setSerializationView(Views.Detailed.class);
return result;
}
사용BeanSerializerModifier
메서드를 확장한 다음 재정의할 수 있습니다.필요에 따라 직렬화할 속성을 추가, 제거 또는 교체할 수 있습니다.
public class CustomSerializerModifier extends BeanSerializerModifier {
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
// In this method you can add, remove or replace any of passed properties
return beanProperties;
}
}
그런 다음 시리얼라이저를 에 모듈로 등록합니다.
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule() {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addBeanSerializerModifier(new CustomSerializerModifier());
}
});
사용.@JsonFilter
와 함께SimpleBeanPropertyFilter
또 다른 접근 방식은 다음과 같습니다.
@JsonFilter("customPropertyFilter")
public class Foo {
private String name;
private String details;
// Getters and setters
}
필요에 따라 메소드를 확장하고 재정의합니다.
public class CustomPropertyFilter extends SimpleBeanPropertyFilter {
@Override
public void serializeAsField(Object pojo, JsonGenerator jgen,
SerializerProvider provider,
PropertyWriter writer) throws Exception {
// Serialize a field
// writer.serializeAsField(pojo, jgen, provider, writer);
// Omit a field from serialization
// writer.serializeAsOmittedField(pojo, jgen, provider);
}
}
그런 다음 에 필터를 등록합니다.
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("customPropertyFilter", new CustomPropertyFilter());
ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);
필터를 "글로벌"로 만들려면, 즉 모든 콩에 적용할 혼합 클래스를 만들고 다음을 사용하여 주석을 달 수 있습니다.@JsonFilter("customPropertyFilter")
:
@JsonFilter("customPropertyFilter")
public class CustomPropertyFilterMixIn {
}
그런 다음 믹스인 클래스를 바인딩합니다.Object
:
mapper.addMixIn(Object.class, CustomPropertyFilterMixIn.class);
public static <T> String getNonNullFieldsSerialized(T object, ObjectMapper objectMapper)throws JsonProcessingException {
Map<String, Object> objectMap = objectMapper.convertValue(object, new TypeReference<Map<String, Object>>() {});
Map<String, Object> objectMapNonNullValues = objectMap.entrySet().stream()
.filter(stringObjectEntry -> Objects.nonNull(stringObjectEntry.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return objectMapper.writeValueAsString(objectMapNonNullValues);
}
null이 아닌 모든 필드는 기본적으로 무시됩니다.마찬가지로 맵 필터 조건을 변경하여 다른 필드를 무시할 수 있습니다.
저는 db에서 가져온 데이터와 restapi를 사용하여 반환하는 데이터에 동적 필터를 구현했습니다.저는 MappingJacksonValue를 사용하는 것을 피했습니다.객체 체인을 연결하는 동안 문제가 발생했기 때문입니다.
@GetMapping("/courses")
public ResponseEntity<JpaResponse> allCourse() throws Exception {
JpaResponse response = null;
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
List<Course> course = service.findAllCourse();
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.filterOutAllExcept("name","reviews");
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("jpafilter", filter).setFailOnUnknownId(false);
ObjectWriter writer = mapper.writer(filterProvider);
String writeValueAsString = writer.writeValueAsString(course);
List<Course> resultcourse = mapper.readValue(writeValueAsString,List.class);
response = new JpaResponse(HttpStatus.OK.name(),resultcourse);
return new ResponseEntity<>(response, HttpStatus.OK);
}
public class JpaResponse {
private String status;
private Object data;
public JpaResponse() {
super();
}
public JpaResponse(String status, Object data) {
super();
this.status = status;
this.data = data;
}
}
언급URL : https://stackoverflow.com/questions/51172496/how-to-dynamically-ignore-a-property-on-jackson-serialization
'sourcecode' 카테고리의 다른 글
세션 상태가 세션 ID를 생성했지만 응답이 응용 프로그램에 의해 이미 플러시되었기 때문에 저장할 수 없습니다."를 발생시키는 원인 (0) | 2023.07.18 |
---|---|
동일한 라인으로 출력하여 이전 출력을 덮어쓰시겠습니까? (0) | 2023.07.18 |
딜레마: Fragments vs Activities: (0) | 2023.07.13 |
불만족스러운 종속성 예외:이름이 'entityManagerFactory'인 빈을 생성하는 동안 오류가 발생했습니다. (0) | 2023.07.13 |
저장한 파일로 패치를 포맷하려면 어떻게 해야 합니까? (0) | 2023.07.13 |