When I send this request:
{"invalidField": "value", "date": "value"}
to my rest service:
@PUT
@Consumes("application/json")
public void putJson(Test content) {
System.out.println(content.toString());
}
I expected to get an exception because:
- There is no invalidField in my domain model.
- Date format is not valid.
But really I get test object with null values. My dmain model is:
public class Test {
private String name;
private Date date;
//getters and setters here
}
I think this is not a valid behavior. How can I fix that?
Thanks for help.
Solution:
As Blaise Doughan said, it is required to extend MOXy's MOXyJsonProvider and override the preReadFrom method to set custom javax.xml.bind.ValidationEventHandler. But the problem is that Jersey's ConfigurableMoxyJsonProvider will always be picked first, unless you write a MessageBodyWriter/MessageBodyReader that is parameterized with a more specific type than Object. To solve this problem it is necessary to disable MOXy and then enable CustomMoxyJsonProvider.
Example:
Create your own feature that extends javax.ws.rs.core.Feature:
@Provider public class CustomMoxyFeature implements Feature { @Override public boolean configure(final FeatureContext context) { final String disableMoxy = CommonProperties.MOXY_JSON_FEATURE_DISABLE + '.' + context.getConfiguration().getRuntimeType().name().toLowerCase(); context.property(disableMoxy, true); return true; } }
Create your own provider that extends MOXyJsonProvider:
@Provider public class CustomMoxyJsonProvider extends MOXyJsonProvider { @Override protected void preReadFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, Unmarshaller unmarshaller) throws JAXBException { unmarshaller.setEventHandler(new ValidationEventHandler() { @Override public boolean handleEvent(ValidationEvent event) { return false; } }); }
}
Add this resources in Application config:
package com.vinichenkosa.moxyproblem; import java.util.Set; import javax.ws.rs.core.Application; @javax.ws.rs.ApplicationPath("webresources") public class ApplicationConfig extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> resources = new java.util.HashSet<>(); addRestResourceClasses(resources); return resources; } private void addRestResourceClasses(Set<Class<?>> resources) { resources.add(com.vinichenkosa.moxyproblem.TestResource.class); resources.add(com.vinichenkosa.moxyproblem.custom_provider.CustomMoxyFeature.class); resources.add(com.vinichenkosa.moxyproblem.custom_provider.CustomMoxyJsonProvider.class); } }