Jetty:默认的servlet上下文路径
我需要设置Servlet(由于某些原因,只有servlet而不是处理程序)来处理war之外的文件。 在这里https://stackoverflow.com/a/28735121/5057736我找到了以下解决方案:
Server server = new Server(8080); ServletContextHandler ctx = new ServletContextHandler(); ctx.setContextPath("/"); DefaultServlet defaultServlet = new DefaultServlet(); ServletHolder holderPwd = new ServletHolder("default", defaultServlet); holderPwd.setInitParameter("resourceBase", "./src/webapp/"); ctx.addServlet(holderPwd, "/*");//LINE N ctx.addServlet(InfoServiceSocketServlet.class, "/info"); server.setHandler(ctx);
这个解决方案有效,这就是我需要的。 但是,一旦我将LINE N更改为ctx.addServlet(holderPwd, "/foo/*");
,它就会停止工作ctx.addServlet(holderPwd, "/foo/*");
。 我试过“/ foo /”,“/ foo”,但结果是一样的 – 我not found
。 为什么? 如何使其适应这种特定的背景? 由于同样的原因,我使用jetty 9.2.15。
DefaultServlet
用于查看contextPath
之后的请求URI。
在您的示例代码中,当您将servlet的url-pattern从/
更改为/foo/*
,在磁盘上查找的结果文件现在包含/foo/
部分。
换句话说,/ /css/main.css
的请求URI导致它希望找到的文件(在磁盘上) ./src/webapp/foo/css/main.css
你的例子有一些缺陷。 对于ServletContextHandler
,拥有一个空的资源库并不明智,因为ServletContext
本身需要访问该配置值。
您可以通过删除来解决这个问题
holderPwd.setInitParameter("resourceBase", "./src/webapp/");
并使用ServletContextHandler.setBaseResource(Resource)代替……
ctx.setResourceBase(Resource.newResource(new File("./src/webapp")));
这将允许以下ServletContext
方法(由无数的servlet库使用)也可以工作
-
String getRealPath(String path)
-
URL getResource(String path)
-
InputStream getResourceAsStream(String path)
-
Set
getResources(String path)
最后,为了使这个设置在ServletContextHandler
得到理解,您将在“默认url-pattern”上添加default
Servlet名称,该名称恰好是作为DefaultServlet
实现的。
喜欢这个:
// Lastly, the default servlet for root content // It is important that this is added last. String defName = "default"; // the important "default" name ServletHolder holderDef = new ServletHolder(defName, DefaultServlet.class); holderDef.setInitParameter("dirAllowed","true"); ctx.addServlet(holderDef,"/"); // the servlet spec "default url-pattern"
现在,如果您还需要从不属于webapp的目录中提供来自请求URI /foo/*
静态内容,您也可以这样做。 这将要求您设置另一个不参与ServletContext
DefaultServlet
。
这种设置的一个例子是……
package jetty; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.resource.PathResource; import java.io.File; import java.nio.file.Path; public class ManyDefaultServlet { public static void main(String[] args) throws Exception { Server server = new Server(); ServerConnector connector = new ServerConnector(server); connector.setPort(8080); server.addConnector(connector); // The filesystem paths we will map Path homePath = new File(System.getProperty("user.home")).toPath().toRealPath(); Path pwdPath = new File(System.getProperty("user.dir")).toPath().toRealPath(); // Setup the basic application "context" for this application at "/" // This is also known as the handler tree (in jetty speak) ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); context.setBaseResource(new PathResource(pwdPath)); server.setHandler(context); // Fist, add special pathspec of "/home/" content mapped to the homePath ServletHolder holderHome = new ServletHolder("static-home", DefaultServlet.class); holderHome.setInitParameter("resourceBase",homePath.toUri().toASCIIString()); holderHome.setInitParameter("dirAllowed","true"); // Use request pathInfo, don't calculate from contextPath holderHome.setInitParameter("pathInfoOnly","true"); context.addServlet(holderHome,"/foo/*"); // must end in "/*" for pathInfo to work // Lastly, the default servlet for root content // It is important that this is last. String defName = "default"; // the important "default" name ServletHolder holderDef = new ServletHolder(defName, DefaultServlet.class); holderDef.setInitParameter("dirAllowed","true"); context.addServlet(holderDef,"/"); // the servlet spec "default url-pattern" server.start(); server.join(); } }
这使用第二个DefaultServlet
,仅使用该DefaultServlet
的唯一资源库,并映射到以/*
结尾的url模式。
最后,告诉第二个DefaultServlet
的init-parameter使用Request URI的pathInfo,而不像通常那样在contextPath上拆分。
有关整个pathInfo,请求URI,contextPath和以
/*
结尾的url-patterns的详细信息,请参阅@ 30thh的有用答案
这个独立的DefaultServlet
声明不参与ServletContext
并且库将无法通过ServletContext
方法查看或访问该DefaultServlet
的内容。 但是,所有传入的HTTP客户端请求都可以通过该url-pattern轻松地请求内容。
- 使用Jetty嵌入式容器时,ServletContextHandler.setResourceBase和ResourceHandler.setResourceBase有什么区别?
- Jetty / SOLR管理员面板密码
- maven依赖关系和手动添加WEB-INF / lib中的jar之间的区别
- Jetty WebSocket api与标准JSR 356 API相比
- 连接到安全的websocket
- 在Jetty中运行的Web应用程序中使用CAC(通用访问卡)对用户进行身份validation,以获取美国政府机构使用的应用程序
- 无效的END标头(错误的中央目录大小)zipException
- 在没有Jetty的情况下运行GWT Speedtracer
- 在Jetty 8.1.12中将dirAllowed设置为false