如何动态忽略Jackson序列化的属性 [英] How to dynamically ignore a property on Jackson serialization
问题描述
我有一个具有多个@ManyToOne关联的实体.我正在使用spring-boot应用程序公开REST API.目前,我有多个REST API,它们返回包括关联在内的整个实体的json响应.
I have an entity with multiple @ManyToOne associations. I am using spring-boot application to expose REST API. Currently I am having multiple REST API's with returns the json response of whole entity including associations.
但是我不想序列化所有REST API中的所有关联对象.例如
But I don't want to serialize all associated objects in all REST API. For example
API-1应该返回父对象+ associationA对象 API-2应该返回parent + associationA + associationB对象 API-3应该返回父+关联B +关联c +关联D
API-1 should return parent + associationA object API-2 should return parent + associationA + associationB object API-3 should return parent + associationB + associationc + associationD
因此,在我的序列化过程中,我想忽略除API-1的associationA以外的所有关联. 对于API-2,我想忽略除A和B以外的其他关联
So, in my serialization process, I want to ignore all association except associationA for API-1. For API-2 I want to ignore other associations except A and B
如何在Jackson序列化过程中动态忽略这些属性.
How to dynamically ignore these properties during Jackson serialization.
注意: 我在同一堂课上,我不想为每个API创建任何dto
Notes: I am having a same class, I am not interested to create any dto for each API
任何建议都会受到赞赏.
Any suggestions are kingly appreciated.
推荐答案
我汇总了三种在Jackson中执行动态过滤的方法.其中之一必须满足您的需求.
I've put together three approaches for performing dynamic filtering in Jackson. One of them must suit your needs.
您可以使用 @JsonView
:
You could use @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
.
Alternatively you can set the view dynamically with MappingJacksonValue
.
@RequestMapping("/foo")
public MappingJacksonValue getFoo() {
Foo foo = new Foo();
MappingJacksonValue result = new MappingJacksonValue(foo);
result.setSerializationView(Views.Detailed.class);
return result;
}
使用BeanSerializerModifier
您可以扩展> c7> ,然后覆盖
Using a BeanSerializerModifier
You could extend BeanSerializerModifier
and then override the changeProperties()
method. It allows you to add, remove or replace any of properties for serialization, according to your needs:
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;
}
}
Then register the serializer as a module in your ObjectMapper
:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule() {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addBeanSerializerModifier(new CustomSerializerModifier());
}
});
另一种方法涉及 @JsonFilter
:
Another approach involves @JsonFilter
:
@JsonFilter("customPropertyFilter")
public class Foo {
private String name;
private String details;
// Getters and setters
}
扩展 SimpleBeanPropertyFilter
并覆盖
Extend SimpleBeanPropertyFilter
and override the serializeAsField()
method according to your needs:
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);
如果要使过滤器成为"global" ,即要应用于所有bean,可以创建一个混合类并用@JsonFilter("customPropertyFilter")
进行注释:
If you want to make your filter "global", that is, to be applied to all beans, you can create a mix-in class and annotate it with @JsonFilter("customPropertyFilter")
:
@JsonFilter("customPropertyFilter")
public class CustomPropertyFilterMixIn {
}
然后将混合类绑定到Object
:
mapper.addMixIn(Object.class, CustomPropertyFilterMixIn.class);
这篇关于如何动态忽略Jackson序列化的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!