Saturday, March 23, 2019

java - JAX-RS / Jersey how to customize error handling?

Answer


Answer





I'm learning JAX-RS (aka, JSR-311) using Jersey. I've successfuly created a Root Resource and am playing around with parameters:



@Path("/hello")
public class HelloWorldResource {

@GET
@Produces("text/html")
public String get(
@QueryParam("name") String name,

@QueryParam("birthDate") Date birthDate) {

// Return a greeting with the name and age
}
}


This works great, and handles any format in the current locale which is understood by the Date(String) constructor (like YYYY/mm/dd and mm/dd/YYYY). But if I supply a value which is invalid or not understood, I get a 404 response.



For example:




GET /hello?name=Mark&birthDate=X

404 Not Found


How can I customize this behavior? Maybe a different response code (probably "400 Bad Request")? What about logging an error? Maybe add a description of the problem ("bad date format") in a custom header to aid troubleshooting? Or return a whole Error response with details, along with a 5xx status code?


Answer



There are several approaches to customize the error handling behavior with JAX-RS. Here are three of the easier ways.




The first approach is to create an Exception class that extends WebApplicationException.



Example:



public class NotAuthorizedException extends WebApplicationException {
public NotAuthorizedException(String message) {
super(Response.status(Response.Status.UNAUTHORIZED)
.entity(message).type(MediaType.TEXT_PLAIN).build());
}
}



And to throw this newly create Exception you simply:



@Path("accounts/{accountId}/")
public Item getItem(@PathParam("accountId") String accountId) {
// An unauthorized user tries to enter
throw new NotAuthorizedException("You Don't Have Permission");
}



Notice, you don't need to declare the exception in a throws clause because WebApplicationException is a runtime Exception. This will return a 401 response to the client.



The second and easier approach is to simply construct an instance of the WebApplicationException directly in your code. This approach works as long as you don't have to implement your own application Exceptions.



Example:



@Path("accounts/{accountId}/")
public Item getItem(@PathParam("accountId") String accountId) {
// An unauthorized user tries to enter

throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}


This code too returns a 401 to the client.



Of course, this is just a simple example. You can make the Exception much more complex if necessary, and you can generate what ever http response code you need to.



One other approach is to wrap an existing Exception, perhaps an ObjectNotFoundException with an small wrapper class that implements the ExceptionMapper interface annotated with a @Provider annotation. This tells the JAX-RS runtime, that if the wrapped Exception is raised, return the response code defined in the ExceptionMapper.


No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...