谁能解释 servlet 映射?
Posted
技术标签:
【中文标题】谁能解释 servlet 映射?【英文标题】:Can anyone explain servlet mapping? 【发布时间】:2010-09-19 01:14:39 【问题描述】:我正在尝试使用 SpringMVC 编写一个 Web 应用程序。通常我只是将一些虚构的文件扩展名映射到 Spring 的前端控制器并愉快地生活,但这次我将使用类似 REST 的 URL,没有文件扩展名。
将上下文路径下的所有内容映射到前端控制器(我们称之为“app”)意味着我也应该处理静态文件,这是我不想做的事情(为什么要重新发明另一个weel?),因此与 tomcat 的默认 servlet(我们称之为“tomcat”)进行某种组合似乎是可行的方法。
我得到了工作做类似的事情
<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 #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>
谁能解释一下?
【问题讨论】:
static.springsource.org/spring-webflow/docs/2.0.x/reference/… 相关: ***.com/a/14225540/814702 【参考方案1】:作为参考,“失败的尝试 #2”在 Tomcat >= 到 6.0.29 的版本中完全正确。
这是在 6.0.29 版中修复的 Tomcat 错误的结果:
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>
【讨论】:
【参考方案2】:我想我可能知道发生了什么事。
在您的工作 web.xml 中,您已将您的 servlet 设置为默认 servlet(如果没有其他匹配项,/ 本身就是调用的默认 servlet),它将响应与另一个映射不匹配的任何请求。
在 Failed 1 中,您的 /* 映射确实是有效的路径映射。使用 web.xml 中的 /* 映射,它会回答除其他路径映射之外的所有请求。根据规范,扩展映射是被显式映射覆盖的隐式映射。这就是扩展映射失败的原因。一切都明确映射到应用程序。
在 Failed 2 中,App 负责一切,除了匹配静态内容映射的内容。为了显示我设置的快速测试中发生了什么。这是一个例子。 /some-static-content-folder/
包含 test.png
试图访问 test.png 我试过了:
/some-static-content-folder/test.png
并且找不到该文件。然而尝试
/some-static-content-folder/some-static-content-folder/test.png
它出现了。因此,Tomcat 默认 servlet(至少 6.0.16)似乎放弃了 servlet 映射,并将尝试使用剩余路径查找文件。根据这篇帖子Servlet for serving static contentJetty 给出了你和我所期待的行为。
有什么原因你不能为你的休息调用映射一个根目录。像 app 映射到 /rest_root/* 之类的东西比您负责 rest_root 文件夹中发生的任何事情,但其他任何地方都应由 Tomcat 处理,除非您进行另一个显式映射。我建议将您的 rest servlet 设置为路径映射,因为它可以更好地声明意图。使用 / 或 /* 似乎不合适,因为您必须列出例外情况。以 SO 为例,我的其余映射将类似于
/users/* 用于用户 servlet
/posts/* 用于帖子 servlet
映射顺序
-
显式(路径映射)
隐式(扩展映射)
默认 (/)
请纠正我的错误。
【讨论】:
“失败尝试 #1”的解释在目标上已失效。还是想不出另一个。 如果 /* 已经映射到“app” servlet,那么映射“/”还能得到什么? 如果使用 /*,映射出 / 并没有任何好处,因为它永远不会被调用。 /* 的缺点是你需要处理所有事情,使用 / 你仍然可以设置扩展映射。 好的,我试图围绕你对案例 #2 的解释来思考。至于您的问题,不,没有特别的理由不创建 /rest_root/* 映射,只是个人喜好。听起来比使用默认映射和扩展映射更简单 :-) 意识到 Servlet 不支持像 '/myAppModules/*/Services/*' 这样的通配符,有点发疯。我可以想到许多其他可以处理此问题的服务器,但不是 Servlet。有趣的是,业余爱好者级 WAMP 可以做到,但不是“企业级”Servlet。【参考方案3】:我从未尝试过像这样映射 servlet,但我会认为 /* 在技术上确实都以 / 开头和以 /* 结尾,即使两者使用相同的字符匹配。
【讨论】:
以上是关于谁能解释 servlet 映射?的主要内容,如果未能解决你的问题,请参考以下文章