Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does getRequestDispatcher("path") look?

Using embedded tomcat, this code:

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:

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

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

like image 650
ThreaT Avatar asked Apr 10 '14 19:04

ThreaT


People also ask

How to get Servlet context path?

The context path always comes first in a request URI. The path starts with a "/" character but does not end with a "/" character. For servlets in the default (root) context, this method returns "". It is possible that a servlet container may match a context by more than one context path.

What is request dispatcher path?

Defines an object that receives requests from the client and sends them to any resource (such as a servlet, HTML file, or JSP file) on the server. The servlet container creates the RequestDispatcher object, which is used as a wrapper around a server resource located at a particular path or given by a particular name.

What is the use of getRequestDispatcher?

The RequestDispatcher interface provides the facility of dispatching the request to another resource it may be html, servlet or jsp. This interface can also be used to include the content of another resource also.


1 Answers

The Servlet Specification explains this

The getRequestDispatcher method takes a String argument 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.

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.

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?

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.

You also ask

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

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.


After your edit, you addWebapp to your Tomcat instance.

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.jsp is in

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.

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

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

and added servlet mappings to this context.

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

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

When you send a request to

/example

since the context path is "", the Context above will be used and the mapping will match the ExampleController registered above. Your Servlet code will execute and reach

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

Note the javadoc of ServletRequest#getRequestDispatcher(String)

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

In other words, this Servlet, ExampleController was registered in the ServletContext mapped to the context path "", ie. root. The path /view2/example2/read.jsp is referring to another context. Since this context doesn't have a mapping for it, it responds with 404.

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

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

Now that you have the ServletContext, you can get a RequestDispatcher for a resource in that context.

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

since ServletContext#getRequestDispatcher(String) states

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 addWebapp method when referencing a JSP file. If a blank page or NullPointerException is displayed, ensure that you have done the following:

  1. Remove all the addWebapp definitions.
  2. Run addContext then addWebApp like this so they both point to ROOT:

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".
like image 86
Sotirios Delimanolis Avatar answered Oct 08 '22 19:10

Sotirios Delimanolis