I need to use @JsonView for throwing Exceptions while deserialization.
My POJO:
public class Contact
{
@JsonView( ContactViews.Person.class )
private String personName;
@JsonView( ContactViews.Company.class )
private String companyName;
}
My Service:
public static Contact createPerson(String json) {
ObjectMapper mapper = new ObjectMapper().configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES , true );
Contact person = mapper.readerWithView( ContactViews.Person.class ).forType( Contact.class ).readValue( json );
return person;
}
public static Contact createCompany(String json) {
ObjectMapper mapper = new ObjectMapper().configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES , true );
Contact company = mapper.readerWithView( ContactViews.Company.class ).forType( Contact.class ).readValue( json );
return company;
}
What I need to achieve is that, if I am trying to create a Person, I need to pass only 'personName'. If I pass 'companyName', I need to throw exception. How can I achieve this with @JsonView? Is there any alternative?
I think @JsonView
is not enough to solve this for you. Here is more info why: UnrecognizedPropertyException is not thrown when deserializing properties that are not part of the view
But i just looked in source code and managed to kinda "hack" this issue with combination of @JsonView
and custom BeanDeserializerModifier
. It'is not pretty, but here is essential part:
public static class MyBeanDeserializerModifier extends BeanDeserializerModifier {
@Override
public BeanDeserializerBuilder updateBuilder(DeserializationConfig config,
BeanDescription beanDesc, BeanDeserializerBuilder builder) {
if (beanDesc.getBeanClass() != Contact.class) {
return builder;
}
List<PropertyName> properties = new ArrayList<>();
Iterator<SettableBeanProperty> beanPropertyIterator = builder.getProperties();
Class<?> activeView = config.getActiveView();
while (beanPropertyIterator.hasNext()) {
SettableBeanProperty settableBeanProperty = beanPropertyIterator.next();
if (!settableBeanProperty.visibleInView(activeView)) {
properties.add(settableBeanProperty.getFullName());
}
}
for(PropertyName p : properties){
builder.removeProperty(p);
}
return builder;
}
}
and here is how you register it on your object mapper:
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new MyBeanDeserializerModifier());
mapper.registerModule(module);
This works for me and i'm getting UnrecognizedPropertyException now:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "companyName" (class Main2$Contact), not marked as ignorable (one known property: "personName"])