Jetty 中的 ServletHandler 和 ServletContextHandler 有啥区别?

Posted

技术标签:

【中文标题】Jetty 中的 ServletHandler 和 ServletContextHandler 有啥区别?【英文标题】:What's the difference between a ServletHandler and a ServletContextHandler in Jetty?Jetty 中的 ServletHandler 和 ServletContextHandler 有什么区别? 【发布时间】:2015-08-24 09:09:09 【问题描述】:

我正在尝试使用嵌入式 Jetty 服务器。我只想根据请求路径将请求映射到不同的 servlet。

创建ServletHandler 并向其中添加servlet 与创建ServletContextHandler 并向其中添加servlet 有什么区别?

例如:

//how is this different...
ServletHandler handler = new ServletHandler();
handler.addServletWithMapping(MyServlet.class, "/path");

//from this?
ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.addServlet(MyServlet.class, "/path");

【问题讨论】:

Jetty 与此无关。这些类在 Servlet 规范中定义,这是您应该查看的地方。应该已经看过了。 @EJP - 据我所知,ServletHandler 和 ServletContextHandler 没有在 Servlet 规范 (docs.oracle.com/javaee/6/api/javax/servlet/package-summary.html) 中定义。也许您指的是 ServletContext。我的问题专门针对 Jetty,我认为没有理由删除相关标签或编辑标题。 @EJP ServletHandler 和 ServletContextHandler 是属于 Jetty 的类,通常用于那些在 Embedded Jetty 中工作的人 【参考方案1】:

大多数 Servlet 需要 javax.servlet.ServletContext 对象才能正常运行。

使用ServletContextHandler 将为ServletContextHandler 中的所有Servlet、过滤器、会话、安全等创建和管理公共ServletContext。这包括正确初始化、加载顺序以及受ServletContext 影响的组件的销毁。

还要注意,ServletHandler 被认为是ServletContextHandler 的内部类,并不意味着像 Jetty 那样“原始”使用。虽然在技术上是可行的,但除了最天真和最简单的 Servlet 实现之外,不鼓励使用它。

【讨论】:

跟进问题:在某些示例中,我看到ServletContextHandler 是使用Server 实例(例如new ServletContextHandler(server, "/");)创建的,有时没有。此外,我还看到ServletContextHandler 使用setHandler (server.setHandler(contextHandler);) 传递给Server 实例。这一切有什么意义?为什么有这么多没有详细文档的选项? 最终结果是一样的,要么你提供有关构造函数或字段的信息,要么让父对象为你连接起来。许多对象生命周期工作在幕后进行,以确保一切正常。【参考方案2】:

例如,您可以使用 ServletContextHandler 创建虚拟主机,并且可以轻松管理上下文。这意味着不同端口上的不同上下文处理程序。

Server server = new Server();
ServerConnector pContext = new ServerConnector(server);
pContext.setPort(8080);
pContext.setName("Public");
ServerConnector localConn = new ServerConnector(server);
localConn.setPort(9090);
localConn.setName("Local");

ServletContextHandler publicContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
publicContext.setContextPath("/");
ServletHolder sh = new ServletHolder(new HttpServletDispatcher());  sh.setInitParameter("javax.ws.rs.Application", "ServiceListPublic");
publicContext.addServlet(sh, "/*");
publicContext.setVirtualHosts(new String[]"@Public");


ServletContextHandler localContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
localContext .setContextPath("/");
ServletHolder shl = new ServletHolder(new HttpServletDispatcher()); shl.setInitParameter("javax.ws.rs.Application", "ServiceListLocal");
localContext.addServlet(shl, "/*");
localContext.setVirtualHosts(new String[]"@Local"); //see localConn.SetName


HandlerCollection collection = new HandlerCollection();
collection.addHandler(publicContext);
collection.addHandler(localContext);
server.setHandler(collection);
server.addConnector(pContext);
server.addConnector(localContext);

【讨论】:

以上是关于Jetty 中的 ServletHandler 和 ServletContextHandler 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

jetty 部署java web工程;报java.err.no jdk错误

jetty 部署java web工程;报java.err.no jdk错误

Day687.Tomcat和Jetty中的对象池技术 -深入拆解 Tomcat & Jetty

嵌入式 Jetty 环境中的 Spring Boot 和 Spring Security 集成

Jetty、Spring 和 SPDY 的 Web 服务器日志中的异常

Jetty 中的 JSR-356 javax websockets(嵌入式和非嵌入式)