users@jersey.java.net

[Jersey] Re: ExceptionMapper and the request

From: cowwoc <cowwoc_at_bbs.darktech.org>
Date: Wed, 30 Jan 2013 12:14:05 -0500

On 30/01/2013 11:01 AM, Craig Ching wrote:
> Hi!
>
> Is there anyway in an ExceptionMapper to get the original request? I
> was thinking that for an Accepts header of application/json I would
> return a JSON response but for an Accepts of text/html I would
> redirect to our main page. Any other way I might accomplish that?
>
> Cheers,
> Craig
Hi Craig,

     Here is what I use:

package com.vetailr.web;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.sun.jersey.api.core.HttpRequestContext;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

/**
  * @author Gili Tzabari
  */
@Provider
@Singleton
public class JsonProcessingExceptionMapper implements
ExceptionMapper<JsonProcessingException>
{
     private final com.google.inject.Provider<HttpRequestContext>
requestContext;

     /**
      * Creates a new JsonProcessingExceptionMapper.
      * <p/>
      * @param requestContext the entity associated with the request
      */
     @Inject
     public
JsonProcessingExceptionMapper(com.google.inject.Provider<HttpRequestContext>
requestContext)
     {
         this.requestContext = requestContext;
     }

     @Override
     public Response toResponse(JsonProcessingException e)
     {
         HttpRequestContext provider = requestContext.get();
         String entity = provider.getEntity(String.class);
         StringBuilder message;
         Throwable cause = e.getCause();
         if (entity.trim().isEmpty())
             message = new StringBuilder("Entity may not be empty");
         else if (cause != null)
             message = new StringBuilder(cause.getMessage());
         else
         {
             message = new StringBuilder(e.getClass().getName() + ": " +
e.getMessage());
             if (e.getLocation() != null)
             {
                 int sourceStart = message.indexOf("Source:");
                 int sourceEnd = message.indexOf("line:", sourceStart);
                 message.delete(sourceStart, sourceEnd);
             }
message.append("\nEntity:\n\"").append(entity).append("\"");
         }
         return
Response.status(Status.BAD_REQUEST).entity(message.toString()).type("text/plain").build();
     }
}

     I believe you should be able to replace the Guice Provider with
@Context HttpRequestContext.

Gili