如何在不为每个资源定义默认处理程序的情况下覆盖所有404页面?

时间:2016-04-04 11:51:04

标签: java jersey jetty dropwizard

在我的Dropwizard项目中,我正在定义一个通用ExceptionMapper<WebApplicationException>

environment.jersey().register(new WebApplicationExceptionMapper());

...但是这似乎没有捕获到任何不匹配路径的404错误。

如果没有为每个资源定义五个defaultHandler()方法,我如何捕获所有404,以便我可以返回自己的错误页面或一些JSON?

所以,如果我的服务有一个resrouce,比如说,/docs,那就是情节:

  • /myservice/docs/helloworld与我的DocsResource中定义的任何@Path都不匹配。它返回一个通用的Jetty 404页面(不是我想要的)

  • /myservice/doesntexist使用异常映射器返回我自己的错误资源(这就是我想要的地方)

1 个答案:

答案 0 :(得分:2)

what you need to do is to set a different Error handler. The 404's you are seeing when hitting a non-existing path, are not handled by jersey. Jersey maps exceptions for resources, but you in fact never hit the resource in the first place. This is where you will need to define an error handler:

In DefaultServerFactory, you need to overwrite:

protected Server buildServer(LifecycleEnvironment lifecycle,
                                 ThreadPool threadPool) {
        final Server server = new Server(threadPool);
        server.addLifeCycleListener(buildSetUIDListener());
        lifecycle.attach(server);
        final ErrorHandler errorHandler = new ErrorHandler();
        errorHandler.setServer(server);
        errorHandler.setShowStacks(false);
        server.addBean(errorHandler);
        server.setStopAtShutdown(true);
        server.setStopTimeout(shutdownGracePeriod.toMilliseconds());
        return server;
    }

(This class is in AbstractServerFactory).

You then can implement your own ErrorHandler and make it do whatever it is you want it to do.

For testing, open org.eclipse.jetty.server.handler.ErrorHandler and set a breakpoint, then try and hit a non-existing URL. It will stop there and you can see how jetty handles this sort of thing.

I hope that helps.

If you need help overwriting default DW functionality, you can look at a similar post where I described how to overwrite loggers:

Dropwizard doesn't log custom loggers to file

Cheers, Artur