How to get content type of the response in JAX-RS ExceptionMapper

1.5k views Asked by At

I have a resource:

@GET
@Path("/print-order")
@Produces("application/pdf")
public byte[] printOrder(@QueryParam("id") Long orderId) {
    return ...;
}

...which can throw an error that is relevant to the user and must be displayed as a HTML page. So I implemented an ExceptionMapper but I don't know how to get the value of @Produces("application/pdf") annotation of the called resource.

@Provider
public class CustomExceptionMapper implements ExceptionMapper<CustomException> {
    @Override
    public Response toResponse(CustomException exception) {
        if (contentType = "application/pdf")
            ... html respone
        else
            ... entity response
    }
}

I'm using JAX-RS 1.x (jsr311) with Jersy 1.12 implementation but would love to have implementation independent solution.

1

There are 1 answers

4
Aleksei Budiak On

You can inject different context objects into the ExceptionMapper to get more info on the request it handles. It's convenient to determine what content type the client expects based on HTTP's Accept header (learn more here).

Below is the example on how you can make ExceptionMapper to respond with different formats based on Accept header specified (or not specified) by your APIs client.

@Provider
public class CustomExceptionMapper implements ExceptionMapper<CustomException> {

   // Inject headers of the request being processed
   @Context
   private HttpHeaders headers;

   // or even all the request details
   @Context
   private HttpServletRequest request;

   @Override
   public Response toResponse(CustomException exception) {
      List<MediaType> acceptedTypes = headers.getAcceptableMediaTypes();
      if (acceptedTypes.contains(MediaType.APPLICATION_JSON)) {
         // respond with entity
      } else {
         // respond with HTML
      }
   }
}

You initial idea can be implemented, though. You can inject HttpServletRequest in your resource class and use setAttribute() method to store application/pdf string within the context of current request. It can be later obtained in ExceptionMapper using getAttribute() method. But I wouldn't recommend to do so unless absolutely necessary. It introduces not so obvious dependencies between components of your code.