我需要设置Servlet(由于某些原因,只有servlet而不是处理程序)来处理war之外的文件.这里https://*.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 / *”);它就会停止工作.我试过“/ foo /”,“/ foo”,但结果是一样的 – 我找不到.为什么?如何使其适应这种特定的背景?由于同样的原因,我使用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)
>设置< String> getResources(String path)
最后,为了使这个设置在ServletContextHandler中得到理解,您将在“default url-pattern”上添加默认的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上拆分.
For more information on what this whole pathInfo, request URI, contextPath, and url-patterns ending in
/*
are all about, see the 07001
这个独立的DefaultServlet声明不参与ServletContext,并且库将无法通过ServletContext方法查看或访问该DefaultServlet中的内容.但是,所有传入的HTTP客户端请求都可以通过该url-pattern轻松地请求内容.