如何在Jetty 8中添加请求日志记录过滤器?

时间:2015-10-20 10:58:00

标签: java servlets filter jetty jetty-8

以下是我设置Jetty服务器的方法:

Server server = new Server(80);
server.setStopAtShutdown(true);

ServletHandler servletHandler = new ServletHandler();
servletHandler.addServletWithMapping(Erreur500Servlet.class, "/generate-error-500");
servletHandler.addServletWithMapping(AresServlet.class, "/ares/*");
servletHandler.addFilterWithMapping(RequestLoggingFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));

server.setHandler(servletHandler);
server.start(); // at com.company.MyPoc.init(MyPoc.java:44)
server.join();

然而,当它开始时,我得到以下例外:

2015-10-20 12:53:07,565 (?:?) [WARN] FAILED com.company.filter.RequestLoggingFilter-896472140: java.lang.NullPointerException 
java.lang.NullPointerException: null
    at org.eclipse.jetty.servlet.FilterHolder.doStart(FilterHolder.java:100) ~[jetty-servlet-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) [jetty-util-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:753) [jetty-servlet-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.servlet.ServletHandler.doStart(ServletHandler.java:183) [jetty-servlet-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) [jetty-util-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:89) [jetty-server-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.server.Server.doStart(Server.java:262) [jetty-server-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) [jetty-util-8.0.1.v20110908.jar:8.0.1.v20110908]
    at com.company.MyPoc.init(MyPoc.java:44) 

我错过了什么?

Jetty 8.0.1.v20110908

2 个答案:

答案 0 :(得分:2)

首先,最重要的是Jetty 8 is EOL (End of Life)

接下来,请使用更新版本的Jetty,Jetty 8.0.1(目前)在当前稳定版本的Jetty之后大约有110个版本。

现在,解释一下发生了什么。

您正在直接使用ServletHandler,这是一个内部类,不是要实例化和直接访问,而是在最简单和最天真的情况下。即服务器只有1(只有1)Servlet,没有过滤器,没有安全性,没有会话处理等......

使用ServletContextHandler并将servlet和过滤器添加到其中。这是正确的方法,因为它建立了ServletContext所有相关的Servlet和过滤器用来协调。

示例(这是从内存完成的,因为Jetty 8.0.1已经很老了,这可能需要一些调整才能在古老的Jetty版本上正常工作)

Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
context.setResourceBase("/path/to/my/static/resources/");
context.setHandler(server);

context.addServlet(Erreur500Servlet.class, "/generate-error-500");
context.addServlet(AresServlet.class, "/ares/*");
context.addFilter(RequestLoggingFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
context.addServlet(DefaultServlet.class, "/");

server.start();
server.join();

值得注意的是:

  • 如果你有静态资源要服务(html,javascript,css,images等等),那么用.setResourceBase(String)设置基本资源路径(添加了一个新的,更好的,.setBaseResource(Resource) Jetty 9)
  • 如果您想提供静态资源或进行错误处理,请不要忘记致电context.addServlet(DefaultServlet.class, "/")

如果您想要自定义错误处理,请使用ServletContextHandler ErrorHandler这样的功能

// Default error handler
ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
errorHandler.addErrorPage(500,"/error");

// Your webapp
ServletContextHandler context = new ServletContextHandler();
context.setErrorHandler(errorHandler);
context.addServlet(MyCustomErrorServlet.class, "/error");
// etc ...

另外值得注意的是,Jetty附带了一个RequestLogHandler,它具有相同的最终目标(但使用Jetty Handler,而不是通过过滤器)。

答案 1 :(得分:1)

以下是我提出的解决方案:

Server server = new Server(80);
server.setStopAtShutdown(true);

ServletContextHandler context = new ServletContextHandler();
context.addServlet(Erreur500Servlet.class, "/generate-error-500");
context.addServlet(AresServlet.class, "/ares/*");
context.addFilter(RequestLoggingFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));

server.setHandler(context);
server.start();
server.join();