问题
I deployed example.war
to Tomcat 6.0.32 (latest at time of writing), and the deployed webapp contains the following:
$ find example | egrep -v "WEB-INF/lib|WEB-INF/classes"
example
example/_items.html
example/_share_link.html
example/all_items.html
example/images
example/images/ajax-loader.gif
example/index.html
example/item
example/item/star.html
example/item.html
example/js
example/js/c-jquery-1.4.2.js
example/js/c-jquery-ui-1.8.2.js
example/js/jquery-1.4.2.js
example/js/jquery-1.4.4.min.js
example/js/jquery-ui-1.8.2.js
example/js/jquery-ui-1.8.8.custom.min.js
example/js/jquery.blockUI.js
example/META-INF
example/META-INF/MANIFEST.MF
example/search.html
example/static
example/static/index.html
example/templates-hidden
example/templates-hidden/default.html
example/templates-hidden/wizard-all.html
example/WEB-INF
example/WEB-INF/web.xml
Particularly note:
example/item
example/item/star.html
example/item.html
I try and request the above resource:
$ telnet localhost 8080
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET /example/item HTTP/1.0
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost:8080/example/item/
Date: Thu, 07 Apr 2011 08:24:39 GMT
Connection: close
Connection closed by foreign host.
The server told me to try /example/item/
$ telnet localhost 8080
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET /example/item/ HTTP/1.0
HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=6D97AD3A8F77697146163946B1BBBB64; Path=/example
Expires: Thu, 7 Apr 2011 08:24:58 UTC
Cache-Control: no-cache, private, no-store
Pragma: no-cache
Date: Thu, 07 Apr 2011 08:24:58 GMT
X-Lift-Version: 2.3
Content-Type: text/html;charset=utf-8
Content-Length: 106
Connection: close
<!DOCTYPE html>
<html> <body>The Requested URL /example/item/ was not found on this server</body> </html>
Connection closed by foreign host.
This is not what I expect. The first request to /example/item
(without the trailing slash) should work -- at this point the Lift web framework takes over and renders my items, using star.html
as a template. This works really well with Jetty 6.1.22 and Resin 4.0.16, but not Tomcat.
Is there some special configuration I'm missing? Is there something in the servlet specification which denotes the correct behaviour in this case?
The example code I used can be found here: https://github.com/dpp/simply_lift/tree/master/samples/shopwithme
I raised the original issue here: https://groups.google.com/forum/?fromgroups#!topic/liftweb/7QlFud1ieOU
Note This question is not about Lift or its rendering pipeline -- it's about Tomcat, and why its behaviour differs from Jetty and Resin's.
UPDATE: This is the classic "trailing slash" issue, and a bug report has been filed here: https://issues.apache.org/bugzilla/show_bug.cgi?id=32424
回答1:
Someone answered this, but the question was phrased quite differently, which is why I'm going to leave my own question as-is (for those users who use different search terms):
Where does Tomcat append / to directory paths?
In a nutshell, see this class:
http://svn.apache.org/repos/asf/tomcat/tc6.0.x/tags/TOMCAT_6_0_26/java/org/apache/tomcat/util/http/mapper/Mapper.java
...and then find a comment detailing 'default servlet' in that class -- it's called "Rule 7", which according to many, is a bug: https://issues.apache.org/bugzilla/show_bug.cgi?id=32424
It will stay unfixed in Tomcat for the foreseeable, according to a comment by one of the developers:
The behavior is not specified anywhere, but the idea is that in the case of a physical folder or the root of a context, the trailing '/' is not relevant. Since this causes recurrent path resolution issues (which made servlets like our default servlet needlessly more complex), we always present the servlet with a training '/' in all cases. It is also the most efficient, so that's the the implementation which is currently used.
I regret it would prevent you from using Tomcat, but there's nothing that I will change here.
来源:https://stackoverflow.com/questions/5578548/lift-webapp-has-directory-and-resource-with-the-same-name-but-gives-302