Java getRequestDispatcher("path") 在哪里看?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22997130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 19:52:50  来源:igfitidea点击:

Where does getRequestDispatcher("path") look?

javatomcatservlets

提问by ThreaT

Using embedded tomcat, this code:

使用嵌入式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());

Prints out:

打印出来:

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

Does that mean that:

这是否意味着:

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

Will look at this URL to forward(request, response)to the JSP:

将查看这个forward(request, response)指向 JSP 的URL :

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

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

Is there a way to print out what absoluteURL getRequestDispatcher("relativePath")is addressing?

有没有办法打印出绝对URLgetRequestDispatcher("relativePath")正在寻址的内容?

采纳答案by Sotirios Delimanolis

The Servlet Specificationexplains this

Servlet规范解释了这个

The getRequestDispatchermethod takes a Stringargument describing a path within the scope of the ServletContext. This path must be relative to the root of the ServletContext and begin with a ‘/', or be empty. The method uses the path to look up a servlet, using the servlet path matching rules in Chapter 12, “Mapping Requests to Servlets”,wraps it with a RequestDispatcher object, and returns the resulting object. If no servlet can be resolved based on the given path, a RequestDispatcher is provided that returns the content for that path.

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

Those rules are the following

这些规则如下

  1. The container will try to find an exact match of the path of the request to the path of the servlet. A successful match selects the servlet.
  2. The container will recursively try to match the longest path-prefix. This is done by stepping down the path tree a directory at a time, using the '/' character as a path separator. The longest match determines the servlet selected.
  3. If the last segment in the URL path contains an extension (e.g. .jsp), the servlet container will try to match a servlet that handles requests for the extension. An extension is defined as the part of the last segment after the last '.' character.
  4. If neither of the previous three rules result in a servlet match, the container will attempt to serve content appropriate for the resource requested. If a "default" servlet is defined for the application, it will be used. Many containers provide an implicit default servlet for serving content.
  1. 容器将尝试找到请求路径与 servlet 路径的精确匹配。成功匹配将选择 servlet。
  2. 容器将递归地尝试匹配最长的路径前缀。这是通过使用“/”字符作为路径分隔符一次一个目录的路径树来完成的。最长的匹配决定了选择的 servlet。
  3. 如果 URL 路径中的最后一段包含扩展名(例如 .jsp),则 servlet 容器将尝试匹配处理扩展名请求的 servlet。扩展名定义为最后一个 '.' 之后的最后一个段的部分。特点。
  4. 如果前三个规则都没有导致 servlet 匹配,则容器将尝试提供适合所请求资源的内容。如果为应用程序定义了“默认”servlet,则将使用它。许多容器提供了一个隐式的默认 servlet 来提供内容。

You ask

你问

Does that mean that:

request.getRequestDispatcher("/example/display.jsp").forward(request, response); Will look at this URL to forward(request, response) to the JSP:

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

这是否意味着:

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

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

No, it doesn't send an HTTP request, so the path has nothing to do with a URI. It's more of an internal path that the Servlet container will try to match with its various url-mappings for Servlets.

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

You also ask

你也问

Is there a way to print out what absolute URL getRequestDispatcher("relativePath") is addressing?

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

No. And it isn't exactly an absolute URL. It's a path that can be handled by some resource in the web application context.

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



After your edit, you addWebappto your Tomcatinstance.

编辑后,您addWebapp将进入您的Tomcat实例。

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

You then send a request to

然后你发送一个请求到

 /view2/example2/read.jsp

I'm going to assume that read.jspis in

我假设那read.jsp是在

src/com/example/view/example/

I believe it's in the publicly accessible part of the web application and therefore the Servlet container can render it and respond with it.

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

You've also added a webapp with addContextwhich seems to be similar to addWebapp

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

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

and added servlet mappings to thiscontext.

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

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

I was wrong about the /example/*not being able to handle /example.

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

When you send a request to

当您向

/example

since the context path is "", the Contextabove will be used and the mapping will match the ExampleControllerregistered above. Your Servletcode will execute and reach

由于上下文路径是“”,因此Context将使用上述内容,并且映射将与ExampleController上面注册的内容相匹配。您的Servlet代码将执行并到达

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

Note the javadoc of ServletRequest#getRequestDispatcher(String)

注意javadoc ServletRequest#getRequestDispatcher(String)

The pathname specified may be relative, although it cannot extend outside the current servlet context.

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

In other words, this Servlet, ExampleControllerwas registered in the ServletContextmapped to the context path "", ie. root. The path /view2/example2/read.jspis referring to another context. Since this context doesn't have a mapping for it, it responds with 404.

换句话说,本ServletExampleController被登记在ServletContext映射到上下文路径"",即。根。该路径/view2/example2/read.jsp指的是另一个上下文。由于此上下文没有对应的映射,因此它以 404 响应。

You can get a reference to another web applications in a different context. You have to use ServletContext#getContext(String). For example

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

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

Now that you have the ServletContext, you can get a RequestDispatcherfor a resource in thatcontext.

现在您有了ServletContext,您可以RequestDispatcher上下文中获取资源的。

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

since ServletContext#getRequestDispatcher(String)states

由于ServletContext#getRequestDispatcher(String)状态

The pathname must begin with a / and is interpreted as relative to the current context root.

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



Final Answer:

最终答案:

getRequestDispatcher("path")will look at the directory set in the addWebappmethod when referencing a JSP file. If a blank page or NullPointerExceptionis displayed, ensure that you have done the following:

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

  1. Remove all the addWebappdefinitions.
  2. Run addContextthen addWebApplike this so they both point to ROOT:
  1. 删除所有addWebapp定义。
  2. addContext然后addWebApp像这样运行,以便它们都指向ROOT

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

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

  1. In the servlet point to the jsp using request.getRequestDispatcher("/example/read.jsp").forward(request, response);provided that the directory /example exists in "src/com/example/view".
  1. 如果request.getRequestDispatcher("/example/read.jsp").forward(request, response);目录 /example 存在于"src/com/example/view".