6

I have a number of classes exposed as JAX-RS request "handlers", using javax.ws.rs.Path annotations. I want to add certain actions before every request and after each request. Also, I need to create a global application-wide exception handler, which will catch everything thrown by these handlers and protocol.

Is it possible to achieve this with standard JAX-RS without creating of a custom class inherited from com.sun.jersey.spi.container.servlet.ServletContainer (I'm using Jersey).

yegor256
  • 102,010
  • 123
  • 446
  • 597
  • The accepted answer doesn't address your desire to have pre and post request actions. Did you ever come to a solution for that? – A. R. Younce May 07 '11 at 00:26
  • Custom [Servlet Filter](http://download.oracle.com/javaee/5/api/javax/servlet/Filter.html) is the way to go. – yegor256 May 07 '11 at 03:58

3 Answers3

3

You can also use ExceptionMappers. This mechanism which catch the exception thrown by your service and convert it to the appropriate Response:

@Provider  
public class PersistenceMapper implements ExceptionMapper<PersistenceException> {  

    @Override  
    public Response toResponse(PersistenceException arg0) {  
        if(arg0.getCause() instanceof InvalidDataException) { 
           return Response.status(Response.Status.BAD_REQUEST).build();  
        } else { 
           ... 
        } 
    }  

}  

For more information see:

Community
  • 1
  • 1
bdoughan
  • 147,609
  • 23
  • 300
  • 400
1

You could create a proxy RESTful service and use this as the entry point to all your other RESTful services. This proxy can receive requests, do any pre-processing, call the RESTful service required, process the response and then return something to the caller.

I have a set up like this in a project I've been working on. The proxy performs functions like authentication, authorisation and audit logging. I can go into further details if you like.

Edit:
Here is an idea of how you might want to implement a proxy that supports GET requests;

@Path("/proxy")
public class Proxy
{
private Logger log = Logger.getLogger(Proxy.class);

@Context private UriInfo uriInfo;

@GET
@Path("/{webService}/{method}")
public Response doProxy(@Context HttpServletRequest req,
                 @PathParam("webService") String webService,
                 @PathParam("method") String method)
{
    log.debug("log request details");

    //implement this method to work out the URL of your end service
    String url = constructURL(req, uriInfo, webService, method);

    //Do any actions here before calling the end service

    Client client = Client.create();
    WebResource resource = client.resource(url);

    try
    {
        ClientResponse response = resource.get(ClientResponse.class);
        int status = response.getStatus();
        String responseData = response.getEntity(String.class);

        log.debug("log response details");

        //Do any actions here after getting the response from the end service,
        //but before you send the response back to the caller.

        return Response.status(status).entity(responseData).build();
    }
    catch (Throwable t)
    {
        //Global exception handler here
        //remember to return a Response of some kind.
    }
}
Qwerky
  • 18,217
  • 6
  • 44
  • 80
  • 1
    Sounds like a solution, but how will you "process the response"? Can you give an example of this RESTful proxy? – yegor256 Oct 12 '10 at 15:44
0

You can use filters to read and modify all requests and responses.

Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67