File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Servlets and the fly likes getRequestDispatcher(), relative path problem... Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Servlets
Bookmark "getRequestDispatcher(), relative path problem..." Watch "getRequestDispatcher(), relative path problem..." New topic
Author

getRequestDispatcher(), relative path problem...

Erik Brakkee
Ranch Hand

Joined: Jun 21, 2004
Posts: 40
Hi all,

I am trying to understand how ServletRequest.getRequestDispatcher(String path) transforms a relative path into an absolute path. I have an example which works (JBoss 3.2.3), but I don't understand why. The Java servlet spec 2.4 also does not help me much because it is not very clear on this point.

The example is as follows:
The servlet forwards a request as follows:

req.getRequestDispatcher("../login.html").forward(req, res);

The file login.html resides in the root of the web archive.

The servlet mapping for this servlet is as follows:

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/servlet/MyServlet/*</url-pattern>
</servlet-mapping>

Now what I would expect would happen is that the request dispatcher would
forward a request for /servlet/MyServlet/ to /servlet/MyServlet/../login.html = /servlet/login.html but instead it manages to locate the servlet in the web root. This is very strange.

Can anyone clarify this behavior? Is the behavior of jboss correct?

Cheers
Erik


SCJP, SCJD, SCWCD, SCBCD
chandana sapparapu
Ranch Hand

Joined: Sep 28, 2002
Posts: 63
Now what I would expect would happen is that the request dispatcher would
forward a request for /servlet/MyServlet/ to /servlet/MyServlet/../login.html = /servlet/login.html but instead it manages to locate the servlet in the web root. This is very strange.


This is not a bug in JBoss. This is the correct behaviour.

The relative path in req.getRequestDispatcher is relative to the current request.
That is, it's rel to MyServlet.
Hence, /servlet/MyServlet/../login.html = /login.html
MyServlet is not a directory. One level up is above servlet in the URL, which is the webapp root.

HTH.
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12769
    
    5

Oh no, not another one. You appear to be depending on the "invoker" servlet. This is not a good idea. See the JavaRanch FAQ on the invoker.
Bill
Erik Brakkee
Ranch Hand

Joined: Jun 21, 2004
Posts: 40
You appear to be depending on the "invoker" servlet.


No I am not. I just checked to see what the behavior is when I change the location to /xyz/MyServlet/* and it still works, so I am not depending on any implicit mappings in TomCat.

It is interesting that the last part of the path ("MyServlet") is treated as a directory for determining relative paths, but could not find this in the spec. The servlet 2.4 spec also has another example which seems to contradict this behavior. On page 64 it states the following:

For
example, in a context rooted at �/� and a request to /garden/tools.html, a request
dispatcher obtained via ServletRequest.getRequestDispatcher("header.html")
will behave exactly like a call to
ServletContext.getRequestDispatcher("/garden/header.html").


The spec says that the relative path is evaluated "against the current servler" (whatever that means). In this case, the servlet path would be /garden and the path info would be /tools.html. Using the same logic as I am seeing in my example, the request should be redirected to /header.html.

So what is the exact rule which is implemented? The spec is, I think too vague. What does it mean "against the current servlet"?

Cheers
Erik
Erik Brakkee
Ranch Hand

Joined: Jun 21, 2004
Posts: 40
Hi,


I have just done an experiment using Tom cat 5.0.25 and I am seeing behavior which is more consistent. Here is how Tomcat 5 determines the absolute URL from the relative one (from the source code):

1. first determine the full URI (= servlet path + pathinfo)
2. look for the last slash character and strip it and everything after it
from the URI
3. treat the remaining path as a directory and apply the relative path
to get the path relative to the context root.

So here is what would happen when my servlet MyServlet is mapped at /xyz/MyServlet and the context root is ServletTest and forwarding is used with the relative path "login.html":
1. URL http://<blah>/ServletTest/xyz/MyServlet
Result http://<blah>/ServletTest/xyz/login.html
2. URL http://<blah>/ServletTest/xyz/MyServlet/
Result http://<blah>/ServletTest/xyz/MyServlet/login.html
3. URL http://<blah>/ServletTest/xyz/MyServlet/a/b/abc.html
Result http://<blah>/ServletTest/xyz/MyServlet/a/b/login.html

Perhaps the spec should be updated to really make the rules explicit.

Cheers
Erik
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: getRequestDispatcher(), relative path problem...