Custom HTTP status response with JAX-RS (Jersey) and @RolesAllowed?

With creating an ExceptionMapper (mapping exceptions of WebApplicationException ) it is possible to "catch" certain exceptions thrown by the application.

Up vote 0 down vote favorite 1 share g+ share fb share tw.

With my very simple JAX-RS service I'm using Tomcat with JDBC realm for authentication, therefore I'm working the the JSR 250 annotations. The thing is that I want to return a custom message body in the HTTP status response. The status code (403) should stay the same.

For example, my service looks like the following: @RolesAllowed({ "ADMIN" }) @Path("/users") public class UsersService { @GET @Produces(MediaType. TEXT_PLAIN) @Consumes({MediaType. APPLICATION_JSON, MediaType.

APPLICATION_XML}) public String getUsers() { // get users ... return ...; } } If a user with a different role than "ADMIN" access the service, I want to change the response message to something like that (depending on the media type xml/json): Not allowed. At the moment Jersey returns the following body: HTTP Status 403 - Forbidden type Status report message Forbidden description Access to the specified resource (Forbidden) has been forbidden. Apache Tomcat/7.0.12 How can I change the default message body?

Is there a way to handle the (maybe thrown) exception to build my own HTTP status response? Java jersey jax-rs jsr250 link|improve this question edited Jun 30 '11 at 5:16 asked Jun 29 '11 at 11:39Stefan928 60% accept rate.

With creating an ExceptionMapper (mapping exceptions of WebApplicationException) it is possible to "catch" certain exceptions thrown by the application: @Provider public class MyExceptionMapper implements ExceptionMapper { @Override public Response toResponse(WebApplicationException weException) { // get initial response Response response = weException.getResponse(); // create custom error MyError error = ...; // return the custom error return Response. Status(response.getStatus()). Entity(error).build(); } } You also need to add the package to your application web.

Xml for registering the provider: com.sun.jersey.config.property. Packages com.myapp. Userservice; // semi-colon seperated com.myapp.mappedexception.

I was facing the same problem and in my case that was the perfect answer. Thanks Stefan! – Lars Oct 13 '11 at 17:40.

REST is build upon HTTP so you don't have to change the default behavior of an authentication failure. Having a 403 error when accessing a resource is enough for the client to clearly understand what appends. The more your resources are HTTP compliant, the more others can understand it.

The problem is there can be various situations a single http error occours. One can be a session time out (results in 403) managed by the AS. Another can be an unauthorized attemp to a rest resource (403).

If you have to programmatically react in different ways on those errors its a good way to customize thems. – Lars Oct 13 '11 at 17:55.

The easiest way to handle this sort of thing is to throw an exception and to register an exception mapper to convert into the kind of message you want to send in that case. So, suppose you throw an AccessDeniedException, you would then have a handler like this (with full class names in places for clarity): @javax.ws" rel="nofollow">javax.ws" rel="nofollow">javax.ws" rel="nofollow">javax.ws.rs.ext. Provider public class AccessDeniedHandler implements javax.ws" rel="nofollow">javax.ws" rel="nofollow">javax.ws" rel="nofollow">javax.ws.rs.ext.

ExceptionMapper { public javax.ws" rel="nofollow">javax.ws" rel="nofollow">javax.ws" rel="nofollow">javax.ws.rs.core. Response toResponse(AccessDeniedException exn) { // Construct+return the response here... return Response. Status(403).

Type("text/plain") . Entity("get lost, loser! ").build(); } } The way in which you register the exception mapper varies according to the framework you're using, but for Jersey you should be fine with just using @Provider.

I'll let you figure out for yourself how you want to generate the kind of error documents that you want, but I do recommend handling failures as HTTP error codes of some kind (that's more RESTful...).

The thing is that Jersey returns it's custom 403 response. I'm not able the throw the AccessDeniedException for authorization since the @RolesAllowed stuff handles this. The HTTP error code should be the some I just want to change the body message.

– Stefan Jun 30 '11 at 5:13 I thought you could do that in Jersey with an ExceptionMapper; I know you can with Apache CXF (though that's configured differently for reasons I've come to appreciate) so I believed it reasonable to at least try given that they're both JAX-RS engines and this is just using the JAX-RS API, but I've no direct experience with Jersey so maybe there's something unexpected in the way. – Donal Fellows Jun 30 '11 at 8:03.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions