Where to throw customized 404 error in jersey when HttpServer can't find a resource
Asked Answered
E

1

9

I want to customize 404 response, that the server (not me) throws whenever it can't find a requested resource, (or throw a customized WebApplicationException myself, if it's possible to test if a requested resource is present in one app? probably a List of resources is stored somewhere?). please don't refer me to solutions that suggest to extend WebApplicationException, because even doing so, my problem is when to throw it?, when resource is not found! but how to express this need in jersey framework

Enplane answered 30/10, 2014 at 18:32 Comment(3)
What did you tried so far? ExceptionMapper could helpful ...Danziger
Which verion of Jersey do you use?Sunderance
it's supposed to be Jersey 2.x, with grizzly-http-server 2.3.0, i'm trying examples here linkEnplane
S
14

Jersey throws javax.ws.rs.NotFoundException when it cannot find an endpoint. Just use an exception mapper to transform it to a response of your choice:

import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {

    public Response toResponse(NotFoundException exception) {
        return Response.status(Response.Status.NOT_FOUND)
                .entity("No such resource")
                .build();
    }
}
Sunderance answered 31/10, 2014 at 10:37 Comment(6)
thank's but unfortunately after adding your code, to the same package where my main class resides, and running curl -g -i http://localhost:8080/base/@@@11 I'm receiving 404 with no content, as far as I know @Provider is here to tell server this is the class to throw when a resource was not found, is this right? then how to make it work?!Enplane
I don't think I need to register it somewhere, is that right?Enplane
If you have configured package scanning and you placed a provider in the specified package then it should work. There are several types of providers in JAX-RS (see more: #13557942). ExceptionMappers allow you to catch any exception you want to handle and produce a custom response. In this case we're handling NotFoundException because it's being thrown by the server when no matching resource is found.Sunderance
enabling package scanning as you stated made it work, I just added final ResourceConfig resourceConfig = new ResourceConfig(); Map<String, String> initParams = new HashMap<String, String>(); initParams.put( ServerProperties.PROVIDER_PACKAGES, NotFoundExceptionMapper.class.getPackage().getName()); and passed resourceConfig to GrizzlyHttpServerFactory.createHttpServer.Enplane
That's great! The other option to register a provider or a resource is to do it individually for each class. In this case it would be resourceConfig.register(NotFoundExceptionMapper.class) or through init params: initParams.put(ServerProperties.PROVIDER_CLASSNAMES, NotFoundExceptionMapper.class). However, package scanning is very useful when you have many resources and providers. You can set it to your root package and then every class annotated with @Resource or @Provider gets registered automatically.Sunderance
just a little comment for Guice users: to be undertaken, your mapper classes need to be bind at startup. Example : bind(JerseyGenericExceptionMapper.class).in(Scopes.SINGLETON); bind(JerseyNotFoundExceptionMapper.class).in(Scopes.SINGLETON); bind(JerseyParamExceptionMapper.class).in(Scopes.SINGLETON);Apgar

© 2022 - 2024 — McMap. All rights reserved.