【问题标题】:Where does getRequestDispatcher("path") look?getRequestDispatcher("path") 在哪里看?
【发布时间】:2014-04-10 19:20:13
【问题描述】:

使用嵌入式tomcat,这段代码:

System.out.println("getServletPath: " + request.getServletPath());
System.out.println("getServletContext: " + request.getServletContext().getContextPath());
System.out.println("getServerName: " + request.getServerName());
System.out.println("getServerPort: " + request.getServerPort());

打印出来:

getServletPath: /example
getServletContext: 
getServerName: localhost
getServerPort: 9090

这是否意味着:

request.getRequestDispatcher("/example/read.jsp").forward(request, response);

将查看此 URL 到 forward(request, response) 到 JSP:

http://localhost:9090/example/read.jsp?

有没有办法打印出 absolute URL getRequestDispatcher("relativePath") 正在寻址?

【问题讨论】:

    标签: java tomcat servlets


    【解决方案1】:

    Servlet Specification 解释了这一点

    getRequestDispatcher 方法采用 String 参数描述 ServletContext 范围内的路径。 此路径必须是 相对于 ServletContext 的根并以“/”开头,或者 为空。该方法使用路径查找 servlet,使用 第 12 章中的 servlet 路径匹配规则,“将请求映射到 Servlets”, 用 RequestDispatcher 对象包装它,并返回 结果对象。如果没有 servlet 可以基于给定的解析 路径,提供了一个 RequestDispatcher 来返回内容 那条路。

    这些规则如下

    1. 容器将尝试查找请求路径与 servlet 路径的完全匹配。成功的匹配选择 servlet。
    2. 容器将递归地尝试匹配最长的路径前缀。这是通过将路径树下移到一个目录来完成的 一次,使用“/”字符作为路径分隔符。最长的 match 确定选择的 servlet。
    3. 如果 URL 路径中的最后一段包含扩展名(例如 .jsp),则 servlet 容器将尝试匹配处理 延期申请。扩展被定义为 最后一个 '.' 字符之后的最后一段。
    4. 如果前三个规则都没有导致 servlet 匹配,则容器将尝试提供适合 请求的资源。如果为 应用程序,它将被使用。许多容器提供了隐含的 提供内容的默认 servlet。

    你问

    这是否意味着:

    request.getRequestDispatcher("/example/display.jsp").forward(request, 回复);将查看此 URL 以转发(请求、响应)到 JSP:

    http://localhost:9090/example/display.jsp?

    不,它不发送 HTTP 请求,因此路径与 URI 无关。它更像是一个内部路径,Servlet 容器将尝试与它的各种 Servlet url-mappings 匹配。

    你也问

    有没有办法打印出 getRequestDispatcher("relativePath") 正在寻址的绝对 URL?

    没有。它并不完全是一个绝对 URL。它是一个可由 Web 应用程序上下文中的某些资源处理的路径。


    编辑后,您将addWebapp 转到您的Tomcat 实例。

    tomcat.addWebapp(null, "/view2/example2", new File("src/com/example/view/example").getAbsolutePath());
    

    然后你发送一个请求到

     /view2/example2/read.jsp
    

    我将假设read.jsp

    src/com/example/view/example/
    

    我相信它位于 Web 应用程序的可公开访问部分,因此 Servlet 容器可以呈现它并用它做出响应。

    您还添加了一个带有 addContext 的 webapp,它似乎类似于 addWebapp

    context = tomcat.addContext("", base.getAbsolutePath());
    

    并将 servlet 映射添加到 this 上下文。

    Tomcat.addServlet(context, "example", new ExampleController());
    context.addServletMapping("/example/*", "example");
    

    我错了 /example/* 无法处理 /example

    当您发送请求时

    /example
    

    由于上下文路径是“”,所以将使用上面的Context,并且映射将匹配上面注册的ExampleController。您的Servlet 代码将执行并到达

    request.getRequestDispatcher("/view2/example2/read.jsp").forward(request, response);
    

    注意ServletRequest#getRequestDispatcher(String)的javadoc

    指定的路径名​​可以是相对的,尽管它不能扩展 在当前 servlet 上下文之外。

    也就是说,这个ServletExampleController注册在映射到上下文路径""ServletContext中,即。根。路径/view2/example2/read.jsp 指的是另一个上下文。由于此上下文没有对应的映射,因此它以 404 响应。

    您可以在不同的上下文中获取对另一个 Web 应用程序的引用。你必须使用ServletContext#getContext(String)。例如

     ServletContext otherContext = request.getServletContext().getContext("/view2/example2");
    

    现在您有了ServletContext,您可以在那个上下文中为资源获取RequestDispatcher

    otherContext.getRequestDispatcher("/read.jsp").forward(request, response);
    

    因为ServletContext#getRequestDispatcher(String) 状态

    路径名必须以 / 开头,并被解释为相对于当前上下文根。


    最终答案:

    getRequestDispatcher("path") 在引用 JSP 文件时将查看在 addWebapp 方法中设置的目录。如果显示空白页或NullPointerException,请确保您已完成以下操作:

    1. 删除所有addWebapp 定义。
    2. 像这样运行addContext 然后addWebApp,这样它们都指向ROOT

    File base = new File("src/com/example/view"); context = tomcat.addContext("", base.getAbsolutePath()); tomcat.addWebapp(null, "/", base.getAbsolutePath());

    1. 在 servlet 中使用 request.getRequestDispatcher("/example/read.jsp").forward(request, response); 指向 jsp,前提是目录 /example 存在于 "src/com/example/view" 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-18
      • 2013-08-20
      • 2023-04-05
      • 2014-04-09
      • 2012-08-24
      • 2010-09-13
      • 1970-01-01
      • 2016-09-16
      相关资源
      最近更新 更多