我使用的是嵌入式Jettyv9.4.x,有以下问题:
我的服务器注册了一个ServletContextListener
final WebAppContext context = new WebAppContext();
// add listener
context.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener() {
@Override
public void lifeCycleStarting(LifeCycle event) {
ContextHandler.Context ctx = context.getServletContext();
ctx.setExtendedListenerTypes(true);
ctx.addListener("LISTENER_CLASS_NAME");
}
});
我的听众被叫到Servet。但是,我的上下文侦听器在下面注册了一个ServletRequestListener
:
servletContext.addListener(foo.MyServletRequestListener.class);
除了以下例外,这是失败的:
java.lang.UnsupportedOperationException
at org.eclipse.jetty.servlet.ServletContextHandler$Context.addListener(ServletContextHandler.java:1506)
而且,当我查看时,上下文似乎没有启用(至少,这个标志使异常被抛出)。
当我使用web.xml
运行相同的应用程序时,一切都可以工作。
如何让contextListener注册一个ServletRequestListener
编辑
在Jetty代码中有明确的注释:
//toggle state of the dynamic API so that the listener cannot use it
这仅在编程添加的监听器上启用--使用的是API而不是web-xml
。
我怎样才能让这件事成功?
发布于 2018-06-27 23:20:38
Jetty中有许多不同类型的侦听器,每个监听器都有各自特定的add/remove/get/set方法集。
您的AbstractLifeCycleListener
是一个Jetty侦听器,专门应用于Jetty内部Jetty内部启动/启动/停止Jetty中的各种bean。
在您的问题中,这个侦听器的实现是不完整的,并且表明您对LifeCycleEvent
缺乏理解(您不是在寻找要启动的特定bean ),您的实现将运行数百次。(启动每个bean一次)。
ServletContext.addListener()
的使用有其周围的规则,并且这些规则指定只能在ServletContext
初始化阶段使用它(不能在此之前,不能在之后)。在这个阶段之外使用ServletContext.addListener()
应该会抛出一个IllegalStateException
( javadoc甚至这么说)
ServletContext.addListener()
还拥有一组有限的servlet侦听器,允许与其一起使用,远远少于在Web中有效或可以在WEB-INF/web.xml
中声明或使用@WebListener
注释标记的侦听器类型的数量。
使用ServletContext.addListener()
的唯一方法是在webapp本身内使用webapp代码,并在webapp自己的类加载器中使用。
使用ServletContext.addListener()
的地方是..。
ServletContainerInitializer.onStartup()
ServletContextListener.contextInitialized()
Filter.init()
Servlet.init()
如您所见,所有这些位置都是从webapp本身定义的。
ServletContextHandler.addEventListener(EventListener)
的存在是一个嵌入式的跳槽,它允许在ServletContextHandler
的构造中添加侦听器,但在实际事件发生之前不会调用。
ServletContextHandler.addEventListener(EventListener)
的使用相当于使用WEB-INF/web.xml
来声明您感兴趣的侦听器。
示例:
package jetty.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
public class ServletContextListenerExample
{
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
MyContextListener contextListener = new MyContextListener();
context.addEventListener(contextListener);
// for context based static file serving and error handling
context.addServlet(DefaultServlet.class, "/");
HandlerList handlers = new HandlerList();
handlers.addHandler(context);
// for non-context error handling
handlers.addHandler(new DefaultHandler());
server.setHandler(handlers);
server.start();
server.join();
}
public static class MyContextListener implements ServletContextListener
{
@Override
public void contextInitialized(ServletContextEvent sce)
{
System.err.printf("MyContextListener.contextInitialized(%s)%n", sce);
sce.getServletContext().addListener(new MyRequestListener());
}
@Override
public void contextDestroyed(ServletContextEvent sce)
{
System.err.printf("MyContextListener.contextDestroyed(%s)%n", sce);
}
}
public static class MyRequestListener implements ServletRequestListener
{
@Override
public void requestDestroyed(ServletRequestEvent sre)
{
System.err.printf("MyRequestListener.requestDestroyed(%s)%n", sre);
}
@Override
public void requestInitialized(ServletRequestEvent sre)
{
System.err.printf("MyRequestListener.requestInitialized(%s)%n", sre);
}
}
}
这将注册MyContextListener
,它实现了两个javax.servlet.ServletContextListener
。当ServletContext
初始化阶段启动时,将触发contextInitialized()
事件。然后,contextInitalized()
的实现使用传入的ServletContext
通过ServletContext.addListener()
API添加一个新的MyRequestListener
(实现javax.servlet.ServletRequestListener
)。
输出上述内容,并从浏览器中点击http://localhost:8080/
.
2018-06-28 09:42:06.352:INFO::main: Logging initialized @340ms to org.eclipse.jetty.util.log.StdErrLog
2018-06-28 09:42:06.475:INFO:oejs.Server:main: jetty-9.4.11.v20180605; built: 2018-06-05T18:24:03.829Z; git: d5fc0523cfa96bfebfbda19606cad384d772f04c; jvm 9.0.4+11
MyContextListener.contextInitialized(javax.servlet.ServletContextEvent[source=ServletContext@o.e.j.s.ServletContextHandler@12e61fe6{/,null,STARTING}])
2018-06-28 09:42:06.532:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@12e61fe6{/,null,AVAILABLE}
2018-06-28 09:42:06.695:INFO:oejs.AbstractConnector:main: Started ServerConnector@4567f35d{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2018-06-28 09:42:06.695:INFO:oejs.Server:main: Started @690ms
MyRequestListener.requestInitialized(javax.servlet.ServletRequestEvent[source=ServletContext@o.e.j.s.ServletContextHandler@12e61fe6{/,null,AVAILABLE}])
MyRequestListener.requestDestroyed(javax.servlet.ServletRequestEvent[source=ServletContext@o.e.j.s.ServletContextHandler@12e61fe6{/,null,AVAILABLE}])
注意:这里讨论的Jetty上还有很多侦听器API和监听器类型,它们存在于与您的问题无关的Jetty的其他特性/组件中。不要被它们挂断,跳过它们,忽略它们,你就会没事的。
https://stackoverflow.com/questions/51072271
复制相似问题