嵌入式Jetty:ServletContextListener,用于注册ServletRequestListener
我使用的是嵌入式Jetty v9.4.x,存在以下问题: 我的服务器注册了一个嵌入式Jetty:ServletContextListener,用于注册ServletRequestListener,jetty,embedded-jetty,Jetty,Embedded Jetty,我使用的是嵌入式Jetty v9.4.x,存在以下问题: 我的服务器注册了一个ServletContextListener: final WebAppContext context = new WebAppContext(); // add listener context.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener() { @Override
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 start上被调用。但是,我的上下文侦听器在以下内部注册了一个ServletRequestListener
:
servletContext.addListener(foo.MyServletRequestListener.class);
此操作失败,但出现以下例外情况:
java.lang.UnsupportedOperationException
at org.eclipse.jetty.servlet.ServletContextHandler$Context.addListener(ServletContextHandler.java:1506)
当我查看时,上下文似乎未启用(至少,该标志会引发异常)
当我用web.xml
运行同一个应用程序时,一切都正常
如何让contextListener注册ServletRequestListener
编辑
码头规范中有明确说明:
//toggle state of the dynamic API so that the listener cannot use it
这仅在通过编程添加的侦听器上启用-使用API而不是WebXML
我怎样才能做到这一点呢?Jetty中有许多不同类型的侦听器,每个侦听器都有自己特定的添加/删除/获取/设置方法集 您的
AbstractLifeCycleListener
是Jetty生命周期监听器,专门用于Jetty内部启动/启动/停止/停止Jetty中的各种bean
您在问题中对该侦听器的实现是不完整的,并且显示出您对LifeCycleEvent
的理解不足(您没有寻找要启动的特定bean),您的实现将运行数百次。(每启动一个bean一次)
的使用有一些规则,这些规则规定它只能在ServletContext
初始化阶段(不在之前,不在之后)使用。在这个阶段之外使用ServletContext.addListener()
应该会抛出一个IllegalStateException
(javadoc甚至这样说)
ServletContext.addListener()
也有一组允许与之一起使用的有限的servlet侦听器,远远少于Web应用程序有效的侦听器类型的数量,或者可以在Web-INF/Web.xml
中声明,或者用@WebListener
注释标记的侦听器类型的数量
使用ServletContext.addListener()
的唯一方法是从webapp本身内部,使用webapp代码,从webapp自己的类加载器内部
要使用的位置是
ServletContextHandler.addEventListener(EventListener)
的存在是一个嵌入式jetty解决方案,它允许在构建ServletContextHandler
时添加侦听器,但在实际事件发生之前不调用侦听器
使用ServletContextHandler.addEventListener(EventListener)
相当于使用WEB-INF/WEB.xml
声明您感兴趣的侦听器
例如:
包jetty.listener;
导入javax.servlet.ServletContextEvent;
导入javax.servlet.ServletContextListener;
导入javax.servlet.ServletRequestEvent;
导入javax.servlet.ServletRequestListener;
导入org.eclipse.jetty.server.server;
导入org.eclipse.jetty.server.handler.DefaultHandler;
导入org.eclipse.jetty.server.handler.HandlerList;
导入org.eclipse.jetty.servlet.DefaultServlet;
导入org.eclipse.jetty.servlet.ServletContextHandler;
公共类ServletContextListenerExample
{
公共静态void main(字符串[]args)引发异常
{
服务器=新服务器(8080);
ServletContextHandler上下文=新的ServletContextHandler();
context.setContextPath(“/”);
MyContextListener contextListener=新的MyContextListener();
addEventListener(contextListener);
//用于基于上下文的静态文件服务和错误处理
addServlet(DefaultServlet.class,“/”);
HandlerList handlers=new HandlerList();
addHandler(上下文);
//用于非上下文错误处理
addHandler(新的DefaultHandler());
setHandler(处理程序);
server.start();
join();
}
公共静态类MyContextListener实现ServletContextListener
{
@凌驾
public void contextInitialized(ServletContextEvent sce)
{
System.err.printf(“MyContextListener.contextInitialized(%s)%n”,sce);
sce.getServletContext().addListener(新的MyRequestListener());
}
@凌驾
公共无效上下文已销毁(ServletContextEvent sce)
{
System.err.printf(“MyContextListener.contextDestroyed(%s)%n”,sce);
}
}
公共静态类MyRequestListener实现ServletRequestListener
{
@凌驾
公共无效请求已销毁(ServletRequestEvent sre)
{
System.err.printf(“MyRequestListener.requestdestromed(%s)%n”,sre);
}
@凌驾
public void requestInitialized(ServletRequestEvent sre)
{
System.err.printf(“MyRequestListener.requestInitialized(%s)%n”,sre);
}
}
}
这将注册MyContextListener
,它同时实现了javax.servlet.ServletContextListener
。
当ServletContext
初始化阶段开始时,将触发contextInitialized()
事件。
contextinitialized()
的实现然后使用传入的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和侦听器类型,这些API和侦听器类型用于其他功能