问题描述
我有一个 REST WS 来更新接收 JSON 字符串作为输入的 bean 对象.
I have a REST WS to update a bean object which receives a JSON string as input.
ABean entity = svc.findEntity(...);
objectMapper.readerForUpdating(entity).readValue(json);
[...]
svc.save(entity);
ABean 是一种复杂类型,还包含其他对象,例如:
class ABean {
public BBean b;
public CBean c;
public String d;
}
svc.save(...) 将保存 bean 和嵌入的对象.
svc.save(...) will save the bean and the embedded objects.
出于安全原因,我想过滤掉一些可以由 JSON 字符串更新的属性,但我想动态执行此操作,以便对于每个 WS(或用户角色)我可以决定要阻止哪些属性被更新(所以我不能简单地使用杰克逊视图)
For security reasons I want to filter out some of the properties that can be updated by the JSON string, but I want to do this dynamically, so that for every WS (or user Role) I can decide which properties to prevent to be updated (so I can't simply use the Jackson Views)
总而言之,有什么方法可以在 JSON 反序列化期间动态过滤掉属性?
To summarize, is there any way I can dynamically filter out properties during JSON Deserialization?
推荐答案
另一种方法是使用 BeanDeserializerModifier:
Another way is using BeanDeserializerModifier:
private static class BeanDeserializerModifierForIgnorables extends BeanDeserializerModifier {
private java.lang.Class<?> type;
private List<String> ignorables;
public BeanDeserializerModifierForIgnorables(java.lang.Class clazz, String... properties) {
ignorables = new ArrayList<>();
for(String property : properties) {
ignorables.add(property);
}
this.type = clazz;
}
@Override
public BeanDeserializerBuilder updateBuilder(
DeserializationConfig config, BeanDescription beanDesc,
BeanDeserializerBuilder builder) {
if(!type.equals(beanDesc.getBeanClass())) {
return builder;
}
for(String ignorable : ignorables) {
builder.addIgnorable(ignorable);
}
return builder;
}
@Override
public List<BeanPropertyDefinition> updateProperties(
DeserializationConfig config, BeanDescription beanDesc,
List<BeanPropertyDefinition> propDefs) {
if(!type.equals(beanDesc.getBeanClass())) {
return propDefs;
}
List<BeanPropertyDefinition> newPropDefs = new ArrayList<>();
for(BeanPropertyDefinition propDef : propDefs) {
if(!ignorables.contains(propDef.getName())) {
newPropDefs.add(propDef);
}
}
return newPropDefs;
}
}
您可以使用以下命令将修改器注册到 ObjectMapper:
You can register the modfier to the ObjectMapper with:
BeanDeserializerModifier modifier = new BeanDeserializerModifierForIgnorables(YourType.class, "name");
DeserializerFactory dFactory = BeanDeserializerFactory.instance.withDeserializerModifier(modifier);
ObjectMapper mapper = new ObjectMapper(null, null, new DefaultDeserializationContext.Impl(dFactory));
然后定义的属性被忽略.如果使用 @JsonAnySetter 注释,则可以忽略 updateBuilder 方法.
Then the defined properties are ignored. You can ignore the updateBuilder method if you use the @JsonAnySetter annotation.
您好,马丁
这篇关于Jackson 在反序列化期间动态过滤属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!