Java 谁能解释servlet映射?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/234210/
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
Can anyone explain servlet mapping?
提问by agnul
I'm trying to write a web application using SpringMVC. Normally I'd just map some made-up file extension to Spring's front controller and live happily, but this time I'm going for REST-like URLs, with no file-name extensions.
我正在尝试使用 SpringMVC 编写一个 Web 应用程序。通常我只是将一些虚构的文件扩展名映射到 Spring 的前端控制器并愉快地生活,但这次我要使用类似 REST 的 URL,没有文件扩展名。
Mapping everything under my context path to the front controller (let's call it "app") means I should take care of static files also, something I'd rather not do (why reinvent yet another weel?), so some combination with tomcat's default servlet (let's call it "tomcat") appears to be the way to go.
将我的上下文路径下的所有内容映射到前端控制器(我们称之为“ app”)意味着我也应该处理静态文件,这是我不想做的事情(为什么要重新发明另一个 Weel?),所以与 tomcat 的默认组合servlet(我们称之为“ tomcat”)似乎是要走的路。
I got the thing to work doing something like
我有工作要做类似的事情
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>tomcat</servlet-name>
<url-pattern>*.ext</url-pattern>
</servlet-mapping>
and repeating the latter for each one of the file extensions of my static content. I'm just wondering why the following setups, which to me are equivalent to the one above, don't work.
并为我的静态内容的每个文件扩展名重复后者。我只是想知道为什么以下设置对我来说等同于上面的设置不起作用。
<!-- failed attempt #1 -->
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>tomcat</servlet-name>
<url-pattern>*.ext</url-pattern>
</servlet-mapping>
<!-- failed attempt #2 -->
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>tomcat</servlet-name>
<url-pattern>/some-static-content-folder/*</url-pattern>
</servlet-mapping>
Can anyone shed some light?
任何人都可以透露一些信息吗?
采纳答案by Philip Tinney
I think I may know what is going on.
我想我可能知道发生了什么。
In your working web.xml you have set your servlet to be the default servlet (/ by itself is the default servlet called if there are no other matches), it will answer any request that doesn't match another mapping.
在您工作的 web.xml 中,您已将 servlet 设置为默认 servlet(如果没有其他匹配项,它本身就是调用的默认 servlet),它将回答与其他映射不匹配的任何请求。
In Failed 1 your /* mapping does appear to be a valid path mapping. With the /* mapping in web.xml it answers all requests except other path mappings. According to the specification extension mappings are implicit mappings that are overwritten by explicit mappings. That's why the extension mapping failed. Everything was explicitly mapped to app.
在失败 1 中,您的 /* 映射似乎是有效的路径映射。使用 web.xml 中的 /* 映射,它回答除其他路径映射之外的所有请求。根据规范,扩展映射是被显式映射覆盖的隐式映射。这就是扩展映射失败的原因。一切都明确映射到应用程序。
In Failed 2, App is responsible for everything, except content that matches the static content mapping. To show what is happening in the quick test I set up. Here is an example. /some-static-content-folder/
contains test.png
在 Failed 2 中,除了与静态内容映射匹配的内容外,App 负责所有内容。为了展示我设置的快速测试中发生了什么。这是一个例子。 /some-static-content-folder/
包含test.png
Trying to access test.png I tried:
尝试访问 test.png 我试过:
/some-static-content-folder/test.png
and the file was not found. However trying
并且未找到该文件。然而尝试
/some-static-content-folder/some-static-content-folder/test.png
it comes up. So it seems that the Tomcat default servlet (6.0.16 at least) drops the servlet mapping and will try to find the file by using the remaining path. According to this post Servlet for serving static contentJetty gives the behavior you and I were expecting.
它出现了。因此,Tomcat 默认 servlet(至少 6.0.16)似乎放弃了 servlet 映射,并将尝试使用剩余路径查找文件。根据这篇文章,用于提供静态内容的 Servlet提供了您和我所期望的行为。
Is there some reason you can't do something like map a root directory for your rest calls. Something like app mapped to /rest_root/* than you are responsible for anything that goes on in the rest_root folder, but anywhere else should be handled by Tomcat, unless you make another explicit mapping. I suggest setting your rest servlet to a path mapping, because it declares the intent better. Using / or /* don't seem appropriate, since you have to map out the exceptions. Using SO as an example, my rest mappings would be something like
有什么原因你不能做一些事情,比如为你的休息调用映射一个根目录。类似于 app 映射到 /rest_root/* 的东西,而不是你负责 rest_root 文件夹中发生的任何事情,但其他任何地方都应该由 Tomcat 处理,除非你进行另一个显式映射。我建议将您的 rest servlet 设置为路径映射,因为它可以更好地声明意图。使用 / 或 /* 似乎不合适,因为您必须映射出异常。以 SO 为例,我的其余映射将类似于
/users/* for the user servlet
/posts/* for the posts servlet
/users/* 用于用户 servlet
/posts/* 用于帖子 servlet
Mapping order
映射顺序
- Explicit (Path mappings)
- Implicit (Extension mappings)
- Default (/)
- 显式(路径映射)
- 隐式(扩展映射)
- 默认 (/)
Please correct anything that I got wrong.
请纠正我做错的任何事情。
回答by Adam Crume
I've never tried to map a servlet like this, but I wouldargue that /* does technically both start with / and end with /*, even though the same character is used for both matches.
我从来没有尝试绘制这样一个servlet,但我会认为,/ *做技术上都开始有/和结束以/ *,即使相同的字符用于两场比赛。
回答by PragmaCoder
For reference, the "failed attempt #2" is perfectly correct in version of Tomcat >= to 6.0.29.
作为参考,“失败的尝试 #2”在 Tomcat >= 到 6.0.29 的版本中是完全正确的。
It was the result of a Tomcat bug that get fixed in version 6.0.29:
这是 6.0.29 版本中修复的 Tomcat 错误的结果:
https://issues.apache.org/bugzilla/show_bug.cgi?id=50026
https://issues.apache.org/bugzilla/show_bug.cgi?id=50026
<!-- Correct for Tomcat >= 6.0.29 or other Servlet containers -->
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/some-static-content-folder/*</url-pattern>
</servlet-mapping>