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 is a complex type containing also other objects e.g.:
class ABean {
public BBean b;
public CBean c;
public String d;
}
svc.save(...) will save the bean and the embedded objects.
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)
To summarize, is there any way I can dynamically filter out properties during JSON Deserialization?
ObjectMapper; ObjectMapper objectMapper = new ObjectMapper(); objectMapper. configure(DeserializationFeature. FAIL_ON_UNKNOWN_PROPERTIES, false); This will now ignore unknown properties for any JSON it's going to parse, You should only use this option if you can't annotate a class with @JsonIgnoreProperties annotation.
ObjectMapper is the main actor class of Jackson library. ObjectMapper class ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions.
The simple readValue API of the ObjectMapper is a good entry point. We can use it to parse or deserialize JSON content into a Java object. Also, on the writing side, we can use the writeValue API to serialize any Java object as JSON output.
Without any annotations, the Jackson ObjectMapper uses reflection to do the POJO mapping. Because of the reflection, it works on all fields regardless of the access modifier.
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;
}
}
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));
Then the defined properties are ignored. You can ignore the updateBuilder method if you use the @JsonAnySetter annotation.
Greetings, Martin
I assume from your description that you can't simply use the @JsonIgnore
annotation to prevent the fields from being serialized for each particular class.
Look at using Jakson mix-ins: mix-ins allow you to substitute a class definition - with the necessary annotations - for data binding. During serialization you can choose a particular mix-in class definition to stand in for the actual class being serialized. Define a set of mix-ins to handle every case, then choose which is appropriate when you serialize a particular bean.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With