4

I have a jersey RESTful service integraed with Spring.The base url mapped in web.xml is /rest/* My service class is below:

@Resource
@Scope("request")
@Path("/service/")
@Component
public class ServiceController {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getApiDetails() {
        return Response.ok("area").build();
    }

    @Path("/area")
    @GET
    @Consumes({ MediaType.APPLICATION_JSON })
    @Produces(MediaType.APPLICATION_JSON)
    public Response processConvertCurrency(
        @QueryParam("length") String length,
        @QueryParam("breadth") String breadth) {
        ......
    }
}

When the following url hit, it will show the available services

<baseurl>/rest/service

output : area

Also <baseurl>/rest/service/area?length=10&breadth20 will return its output correctly.

My requirement is that when someone hit <baseurl>/rest/service/volume it should output like

Service is unavailable message.

Since only area is available How can I do that.Please help..(currently 404 error is displayed)

Tom Sebastian
  • 3,123
  • 4
  • 24
  • 50

1 Answers1

3

JAX-RS (Jersey) will throw a NotFoundException if the resource isn't found. This exception will be mapped to a response containing a status code 404 Not Found (with no entity body), as this is normal REST behavior. But we are also allowed to change the response to our liking by creating an ExceptionMapper. There we can set an entity body. You might have something like

import javax.ws.rs.NotFoundException;
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;

@Provider
public class NotFoundExceptionMapper
        implements ExceptionMapper<NotFoundException> {
    final String html
            = "<p style='font-size:20px;font-family:Sans-serif'>"
            + "Service is unavailable message."
            + "</p>"
            + "<a href='http://www.stackoverflow.com'>"
            + "Check out Stackoverflow</a>";

    @Override
    public Response toResponse(NotFoundException e) {
        return Response.status(Status.NOT_FOUND)
                .entity(html).build();
    }
}

We just need to register this provider with the Jersey (JAX-RS) application (possibly through the ResourceConfig).

It seems as long as we have a entity body with the response, we'll get

enter image description here

Instead of a

enter image description here


  • See Exception Mapping
  • Note: you could just as easily simply map 404 to an error page of your choosing, through the web.xml, without the need for any ExceptionMapper. Something like

    <error-page>
        <error-code>404</error-code>
        <location>/error.html</location>
    </error-page>
    

    See here for more details


UPDATE

"One more doubt, when I set it, for all 404 same message. Can we customize too based on the request url or some otherway.(My intention is to provide different message for different services)"

You can inject different contexts into the ExceptionMapper. For instance UriInfo, and get the requested path

@Context
UriInfo uriInfo;

@Override
public Response toResponse(NotFoundException e) {
    String html
        = "<p style='font-size:20px;font-family:Sans-serif'>"
        + "Service is unavailable message."
        + "</p>"
        + "<a href='http://www.stackoverflow.com'>"
        + "Check out Stackoverflow</a>";
    html += "<p>Requested URI: " + uriInfo.getAbsolutePath() + "</p>";
    return Response.status(Status.NOT_FOUND)
            .entity(html).build();
}

enter image description here

There are other contexts that can be injected. Whether they are inject-able into a class depends on the class (resource class / provider class) and its application scope (among other things). But here's a list of inject-able contexts (with the @Context annotation).

  • javax.ws.rs.core.HttpHeaders
  • javax.ws.rs.core.UriInfo
  • javax.ws.rs.core.Request
  • javax.servlet.HttpServletRequest
  • javax.servlet.HttpServletResponse
  • javax.servlet.ServletConfig
  • javax.servlet.ServletContext
  • javax.ws.rs.core.SecurityContext
  • Possible more :-)
Paul Samsotha
  • 188,774
  • 31
  • 430
  • 651
  • Thanks it(ExceptionMapper) works.One more doubt, when I set it, for all 404 same message. Can we customize too based on the request url or some otherway.(My intention is to provide different message for different services) – Tom Sebastian Nov 13 '14 at 12:41