JAX-RS: Handling exceptions from method invocation during JSON deserialization using exception mapper

I’m developing a RESTful API using JAX-RS. One of its interfaces serves the purpose of adding new entities to a database; the entities are supplied as JSON objects. Now, JAX-RS supports deserializing those objects "on the fly" before invoking the method that handles the API request, making it possible to get an object of the actual Java class the JSON object should be mapped to:

@POST @Consumes(APPLICATION_JSON) @Produces(APPLICATION_JSON) public City createCity(City city) {     // persist city in some fashion and return it } 

City has an attribute containing its name. The name, for arbitrary reasons, must not be longer than 32 characters. The setter for that attribute checks this condition and throws an exception in case the condition is not met.

public void setName(String name) {     if (name == null || name.length() > 32)         throw new IllegalCityNameException();     // set city name } 

That exception is in turn mapped to a response through an ExceptionMapper:

@Provider public class InvalidCityNameExceptionMapper implements ExceptionMapper<InvalidCityNameException> {     @Override     public Response toResponse(final InvalidCityNameException e) {         // create and return appropriate response     } } 

What I would like to happen is that in case the JSON object provided by the client violates the city name length constraint, the InvalidCityNameException that is thrown is handled by InvalidCityNameExceptionMapper. This works fine if the exception occurs when creating an instance of City "manually" (e.g. after receiving the attributes in a APPLICATION_FORM_URLENCODED request), but with the above approach of accepting JSON, the InvalidCityNameException is wrapped in further exceptions:

org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage An unexpected error occurred during error handling. No further error processing will occur.     org.apache.cxf.interceptor.Fault         <snip>     Caused by: javax.json.bind.JsonbException         <snip>     Caused by: org.apache.johnzon.mapper.MapperException         <snip>     Caused by: java.lang.reflect.InvocationTargetException         <snip>     Caused by: com.example.City$InvalidCityNameException: City name is too long (max. 32 characters)         <snip> 

I realize why this happens (method invocation through reflection working the way it does), however, I would like to know if there are ways around this that are more elegant than explicitly copying each individual attribute from a generic JSON object to the City instance.

Add Comment
0 Answer(s)

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.