问题描述
我有一个具有多个 @ManyToOne
关联的实体.我正在使用 spring-boot 来公开一个 REST API.目前,我有多个 REST API,它们返回整个实体的 JSON 响应,包括关联.
I have an entity with multiple @ManyToOne
associations. I am using spring-boot to expose a REST API. Currently, I have multiple REST API's which return a JSON response of the whole entity, including associations.
但我不想序列化所有 REST API 中的所有关联对象.
But I don't want to serialize all associated objects in all REST APIs.
例如
- API-1 应该返回 parent + associationA 对象
- API-2 应该返回 parent + associationA + associationB 对象
- API-3 应该返回父级 + 关联 B + 关联 C + 关联 D
所以,在我的序列化过程中,我想忽略除 API-1 的 AssociationA 之外的所有关联.
So, in my serialization process, I want to ignore all association except associationA for API-1.
对于 API-2,我想忽略除 A 和 B 之外的其他关联
For API-2 I want to ignore other associations except A and B
如何在 Jackson 序列化期间动态忽略这些属性?
How do I dynamically ignore these properties during Jackson serialization?
注意事项:我为每个使用相同的类;我对为每个 API 创建 DTO 不感兴趣.
Notes:I'm using the same class for each; I am not interested in creating a DTO for each API.
非常感谢任何建议.
推荐答案
我已经将三种在 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
您可以扩展BeanSerializerModifier
然后覆盖 changeProperties()
方法.它允许您根据需要添加、删除或替换任何用于序列化的属性:
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;
}
}
然后将序列化程序注册为ObjectMapper
:
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
并覆盖 serializeAsField()
方法根据您的需要:
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);
如果你想让你的过滤器全局",即应用到所有的beans,你可以创建一个mix-in类并用@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 {
}
然后将mix-in类绑定到Object
:
Then bind the mix-in class to Object
:
mapper.addMixIn(Object.class, CustomPropertyFilterMixIn.class);
这篇关于如何动态忽略 Jackson 序列化的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!