当前位置: 首页 > 面试题库 >

码头:默认servlet上下文路径

汝跃
2023-03-14
问题内容

我需要设置Servlet(由于某些原因,只有Servlet而不是处理程序)才能在war之外使用文件。在这里我找到了以下解决方案:

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”,但是结果是相同的-我得到了not found。为什么?如何在特定背景下使用它?由于相同的原因,我使用码头9.2.15。


问题答案:

DefaultServlet设计看后请求URI contextPath

在示例代码中,当您将servlet的url模式从/更改/foo/*为要在磁盘上查找的结果文件时,现在包括该/foo/部分。

换句话说,请求URI的/css/main.css结果在文件(在磁盘上)中它期望找到为./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<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"

现在,如果您 需要将请求URI中的静态内容提供/foo/*给不属于该Web
应用程序的目录,那么您也可以这样做。这将要求您设置另一个DefaultServlet不参与的ServletContext

此设置的一个示例是…

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参数使用RequestURI的pathInfo,而不像通常那样在contextPath上拆分。

有关整个pathInfo,请求URI,contextPath和以url模式结尾的/*内容的更多信息,请参见@
30thh的有用答案。

该独立DefaultServlet声明不参与,ServletContext并且库将无法DefaultServlet通过ServletContext方法查看或访问其中的内容。但是,所有传入的HTTP客户端请求都可以通过该url模式轻松地请求内容。



 类似资料:
  • 我需要设置Servlet(由于某些原因,只有Servlet而不是handler)来处理WAR以外的文件。在这里https://stackoverflow.com/a/28735121/5057736我找到了以下解决方案: 这个解决方案的工作,这是我需要的。但是,当我将第N行更改为时,它就停止工作。我尝试了“/foo/”和“/foo”,但是结果是一样的--我得到了。为什么?我怎样才能使它在这种特定的

  • 问题内容: 我有一个静态html,imgs,flash内容文件夹,它位于webapp文件夹之外。现在,我正在使用符号链接将该文件夹映射到我的webapp目录中。我的问题是,当我取消部署应用程序时,它会遵循符号链接并删除所有这些文件。 我尝试实现的解决方案之一是特殊的servlet,它包装了默认的servlet,但是使用了不同的相对路径。我在找出如何以覆盖默认servlet路径的方式包装默认serv

  • 我将Spring Boot与Jetty一起使用,当我从servletContext获取路径时。getRealPath(“/”)结果如下: 但应该像那样或至少类似于: 还有一个有趣的事实是,如果我有webapp文件夹,jetty会在其中使用这个文件夹,比如servlet context和servlet context。getRealPath(“/”)将返回正常路径。 为什么Jetty对servlet

  • 问题内容: 我正在使用码头9.0.3。 如何将URL(例如www.myweb.com/{servlet}/{parameter})映射到给定的servlet和参数? 例如,URL’/ client / 12312’将路由到clientServlet,其方法将接收12312作为参数。 问题答案: 您将有两个部分需要担心。 您的pathSpec Servlet中的HttpServletRequest.

  • 我正在尝试使用sping-boot-starter-webflow和reactive Netty创建sping-boot-2 REST api。我正在尝试根据要在Spring-Boot-2中定义的application.yml中定义的新属性设置上下文路径。 然而,它看起来像网络流量,Netty不使用/识别application.yml.中定义的这个属性 如果我使用spring boot start

  • 我正在使用Jetty的Spring靴。我配置上下文路径: 访问时http://localhost:8080/test,它不起作用。但是去http://localhost:8080/test/作品 是/测试和/测试/不同吗?我如何访问http://localhost:8080/test