我有一个具有多个@ManyToOne
关联的实体。我正在使用spring引导来公开REST。目前,我有多个REST,它们返回整个实体的JSON响应,包括关联。
但我不想序列化所有REST中的所有相关对象。
例如
因此,在我的序列化过程中,除了associationA的API-1之外,我想忽略所有关联。
对于API-2,我想忽略除A和B之外的其他关联。
如何在Jackson序列化期间动态忽略这些属性?
注意:我对每个API都使用相同的类;我不感兴趣为每个API创建一个DTO。
任何建议都会受到国王的赞赏。
发布于 2018-07-04 11:29:07
我把三种在杰克逊中执行动态过滤的方法组合在一起。其中之一必须适合你的需要。
使用@JsonView
您可以使用@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;
}
或者,您可以使用MappingJacksonValue
动态设置视图。
@RequestMapping("/foo")
public MappingJacksonValue getFoo() {
Foo foo = new Foo();
MappingJacksonValue result = new MappingJacksonValue(foo);
result.setSerializationView(Views.Detailed.class);
return result;
}
使用BeanSerializerModifier
您可以扩展BeanSerializerModifier
,然后重写changeProperties()
方法。它允许您根据需要添加、删除或替换任何用于序列化的属性:
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
中的一个模块。
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule() {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addBeanSerializerModifier(new CustomSerializerModifier());
}
});
将@JsonFilter
与SimpleBeanPropertyFilter
结合使用
另一种方法涉及到@JsonFilter
@JsonFilter("customPropertyFilter")
public class Foo {
private String name;
private String details;
// Getters and setters
}
扩展SimpleBeanPropertyFilter
并根据需要重写serializeAsField()
方法:
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);
}
}
然后在ObjectMapper
中注册过滤器
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("customPropertyFilter", new CustomPropertyFilter());
ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);
如果希望使筛选器“全局”,即应用于所有bean,则可以创建混合类并使用@JsonFilter("customPropertyFilter")
对其进行注释。
@JsonFilter("customPropertyFilter")
public class CustomPropertyFilterMixIn {
}
然后将混合类绑定到Object
。
mapper.addMixIn(Object.class, CustomPropertyFilterMixIn.class);
发布于 2022-01-18 13:54:53
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);
}
这将基本上忽略所有非空字段。同样,您可以通过更改映射筛选条件来忽略其他字段。
发布于 2021-06-14 02:52:21
我对从db获取数据并使用rest返回数据实现了动态筛选。我避免使用MappingJacksonValue.As,它在对象链接时遇到问题。
@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;
}
}
https://stackoverflow.com/questions/51172496
复制相似问题