我正在尝试在嵌入式Jetty设置中为Jersey配置LoggingFilter
。使用的胶水代码如下:
ServletContainer servletContainer = new ServletContainer(application);
ServletHolder servletHolder = new ServletHolder(servletContainer);
servletHolder.setInitParameter("com.sun.jersey.config.feature.Debug", "true");
servletHolder.setInitParameter("com.sun.jersey.config.feature.Trace", "true");
servletHolder.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters",
"com.sun.jersey.api.container.filter.LoggingFilter");
servletHolder.setInitParameter("com.sun.jersey.spi.container.ContainerResponseFilters",
"com.sun.jersey.api.container.filter.LoggingFilter");
但实际上忽略了日志记录过滤器,我在控制台中看不到相关日志。我怎样才能做到这一点?在Jersey 1.x和2.x上进行了测试。
relevant answer介绍了如何使用web.xml
实现此目的。
答案 0 :(得分:4)
如果ServletContainer
不是一个彻头彻尾的错误,我认为这是一个非常微妙的细微差别。关于init params主题的ServletContainer
docs读作:
所有初始化参数都作为创建的ResourceConfig的属性添加。
答案隐藏在那里。具体来说,如果ServletContainer没有创建ResourceConfig实例,那么servlet init参数不会作为属性添加,因此不会影响应用程序的配置。当您提供自己的Application
实例时,就像使用new ServletContainer(application)
一样,初始化大致遵循以下过程:
您的代码使用您的ServletContainer
实例调用以下Application
构造函数:
public ServletContainer(Application app) {
this.app = app;
}
容器初始化您的ServletContainer
,作为典型Servlet
生命周期的一部分:
protected void init(WebConfig webConfig) throws ServletException {
webComponent = (app == null)
? new InternalWebComponent()
: new InternalWebComponent(app);
webComponent.init(webConfig);
}
将Application
实例转换为InternalWebComponent
构造函数。 InternalWebComponent
只是WebComponent
的轻微自定义,因此:
InternalWebComponent(Application app) {
super(app);
}
调用:
public WebComponent(Application app) {
if (app == null)
throw new IllegalArgumentException();
if (app instanceof ResourceConfig) {
resourceConfig = (ResourceConfig) app;
} else {
resourceConfig = new ApplicationAdapter(app);
}
}
由于您直接提供了Application
个实例,因此在第二个ResourceConfig
的一个分支中为您构建if
。在构建之后,立即在新组件上调用WebComponent.init()
(请参阅上面的ServletContainer.init()
调用,我们来自哪里)。在这个init()
调用内部,文档引用的“创建的ResourceConfig”将被创建,但在您的情况下,已经存在,如我们遵循的跟踪到此处所示。即,resourceConfig
不为空,因此下面的重要行不会执行:
public void init(WebConfig webConfig) throws ServletException {
...
if (resourceConfig == null)
resourceConfig = createResourceConfig(config);
...
}
createResourceConfig()
方法(仍在WebComponent
中)读作:
private ResourceConfig createResourceConfig(WebConfig webConfig)
throws ServletException {
final Map<String, Object> props = getInitParams(webConfig);
final ResourceConfig rc = createResourceConfig(webConfig, props);
rc.setPropertiesAndFeatures(props);
return rc;
}
您可以在该调用中看到setPropertiesAndFeatures()
用于将servlet的init参数复制到ResourceConfig
实例中。不幸的是,这是进行该调用的唯一位置,在您的情况下,执行永远不会在此处进行,主要是因为您使用了一个非默认的ServletContainer
构造函数。
我希望原作者只用一个no-arg构造函数编写ServletContainer
,然后添加其他两个以便于使用Servlet 3.0容器,而不会意识到这种行为是在引入的。否则,我希望在文档中看到一些提及它。
所以,长话短说:要么使用默认的ServletContainer
构造函数,要么找到一种方法来自己处理这个部分:
Map<String, Object> props = getInitParams(webConfig);
rc.setPropertiesAndFeatures(props);
第一种方式可能是最简单的方法。例如,您可以将Application
类指定为init参数,只要没有要求您提前实例化它,例如:
servletHolder.setInitParameter("javax.ws.rs.Application", "org.foo.MyApplication");
这样,将采用“正常”初始化路径,这意味着WebComponent
将为您创建ResourceConfig
并正确应用init参数。
答案 1 :(得分:0)
我认为你可能做错了。
// Creating an instance of Jersey servlet, right?
ServletContainer servletContainer = new ServletContainer(application);
// Putting it in a container by reference.
ServletHolder servletHolder = new ServletHolder(servletContainer);
This page不像你那样创建servlet:
ServletHolder sh = new ServletHolder(WicketServlet.class);
这样Jetty就会创建一个实例,并调用servlet的init()
。
在您的情况下,您可能需要致电init()
,但我不确定您将在何处获得ServletConfiguration
个实例。
<强>更新强> 你应该这样试试:
ServletHolder servletHolder = new ServletHolder(ServletContainer.class);
servletHolder.setInitParameter("javax.ws.rs.Application", "MyRESTApplication");
servletHolder.setInitParameter("com.sun.jersey.config.feature.Debug", "true");
servletHolder.setInitParameter("com.sun.jersey.config.feature.Trace", "true");
servletHolder.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters",
"com.sun.jersey.api.container.filter.LoggingFilter");
servletHolder.setInitParameter("com.sun.jersey.spi.container.ContainerResponseFilters",
"com.sun.jersey.api.container.filter.LoggingFilter");
ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
contextHandler.addServlet(servletHolder, "/services/*");
server.setHandler(contextHandler);