Context Path + servlet path + path info = request uri

                        |-- Context Path --|-- Servlet Path -|--Path Info--|
http://www.myserver.com     /mywebapp        /helloServlet      /hello
                        |-------- Request URI  ----------------------------|


Remember the following three points:
1. Request URI = context path + servlet path + path info.
2. Context paths and servlet paths start with a / but do not end with it.
3. HttpServletRequest provides three methods getContextPath(),
    getServletPath() and getPathInfo() to retrieve the context path,
    the servlet path, and the path info, respectively, associated with a request.


Identifying the servlet path
To match a request URI with a servlet, the servlet container follows a simple algorithm.
Once it identifies the context path, if any, it evaluates the remaining part of the
request URI with the servlet mappings specified in the deployment descriptor, in the
following order. If it finds a match at any step, it does not take the next step.

1 The container tries to match the request URI to a servlet mapping. If it finds a
match, the complete request URI (except the context path) is the servlet path. In
this case, the path info is null.
2 It tries to recursively match the longest path by stepping down the request URI
path tree a directory at a time, using the / character as a path separator, and determining
if there is a match with a servlet. If there is a match, the matching part
of the request URI is the servlet path and the remaining part is the path info.
3 If the last node of the request URI contains an extension (.jsp, for example),
the servlet container tries to match it to a servlet that handles requests for the
specified extension. In this case, the complete request URI is the servlet path
and the path info is null.
4 If the container is still unable to find a match, it will forward the request to the
default servlet. If there is no default servlet, it will send an error message indicating
the servlet was not found.



<servlet-mapping>
    <servlet-name>RedServlet</servlet-name>
    <url-pattern>/red/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>RedServlet</servlet-name>
    <url-pattern>/red/red/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>RedBlueServlet</servlet-name>
    <url-pattern>/red/blue/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>BlueServlet</servlet-name>
    <url-pattern>/blue/</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>GreenServlet</servlet-name>
    <url-pattern>/green</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>ColorServlet</servlet-name>
    <url-pattern>*.col</url-pattern>
</servlet-mapping>


Request URI                Servlet Used            Servlet Path        Path Info
/colorapp/red                RedServlet              /red                 null
/colorapp/red/               RedServlet              /red                 /
/colorapp/red/aaa            RedServlet              /red                 /aaa

/colorapp/red/blue/aa        RedBlueServlet          /red/blue            /aa
/colorapp/red/red/aaa        RedServlet              /red/red             /aaa
/colorapp/aa.col             ColorServlet            /aa.col              null

/colorapp/hello/aa.col       ColorServlet            /hello/aa.col        null
/colorapp/red/aa.col         RedServlet              /red                 /aa.col
/colorapp/blue               NONE(Error message)                         
/colorapp/hello/blue/        NONE(Error message)                         
/colorapp/blue/mydir         NONE(Error message)
    
/colorapp/blue/dir/aa.col    ColorServlet            /blue/dir/aa.col     null 
/colorapp/green              GreenServlet            /green               null

解释一下:
这里的三个错误,都是错在blue上,注意blue的mapping url是/blue/而不是/blue或者/blue/*这是造成错误的主要原因

==================================================================================================

2010-06-30 15:44

spring MVC的困惑--url-pattern的/和/*有区别

今天试了下spring mvc遇到个很奇怪的事情,按照书上配置访问时总是出现如下警告:

org.springframework.web.servlet.DispatcherServlet noHandlerFound
警告: No mapping found for HTTP request with URI [/myspring/WEB-INF/jsp/hello.jsp] in DispatcherServlet with name 'spring'

web.xml

Xml代码
  1. <servlet>  
  2.   <servlet-name>spring</servlet-name>  
  3.   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.   <init-param>  
  5.      <param-name>contextConfigLocation</param-name>  
  6.      <param-value>/WEB-INF/springContext.xml</param-value>  
  7.   </init-param>  
  8. </servlet>  
  9.   
  10. <servlet-mapping>  
  11.   <servlet-name>spring</servlet-name>  
  12.   <url-pattern>/*</url-pattern>  
  13. </servlet-mapping>  
<servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springContext.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>

 springContext.xml

Xml代码
  1. <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  2.     <property name="prefix" value="/WEB-INF/jsp/" />  
  3.     <property name="suffix" value=".jsp" />  
  4.  </bean>  
  5.        
  6.  <bean name="/hc"  class="com.hj.controllers.HelloController"/>  
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <bean name="/hc" class="com.hj.controllers.HelloController"/>

   HelloController.java

Java代码
  1. @Override  
  2. protected ModelAndView handleRequestInternal(HttpServletRequest request,  
  3.         HttpServletResponse response) throws Exception {  
  4.   
  5.     return new ModelAndView("hello");  
  6. }  
@Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("hello"); }

   在项目/WEB-INF/jsp目录下防止hello.jsp文件。按照上述配置访问http://localhost:8081/myspring /hc,应该是出现hello.jsp内容才对,但是却出现了一开始提到的警告。我搜索了许多地方,结果在一老外的提供中找到了同样的问题(http: //forum.springsource.org/archive/index.php/t-71263.html),解决方法老外也说明了,只是不知 道为什么。

  就是将web.xml中

Xml代码
  1. <servlet-mapping>  
  2.     <servlet-name>spring</servlet-name>  
  3.     <url-pattern>/*</url-pattern>  
  4.   </servlet-mapping>  
<servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>

  改成

 

Java代码
  1. <servlet-mapping>  
  2.     <servlet-name>spring</servlet-name>  
  3.     <url-pattern>/</url-pattern>  
  4.   </servlet-mapping>  
<servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>

   然后按照上述地址就可以访问,但是这是为什么呢?有谁知道请留言,不胜感谢!


问题补充
我 的意思就是为什么/*无法匹配,而/却可以匹配到
原文:http://www.javaeye.com/problems/36433

————————————————————————————————————————————
上述问题我也遇到,所以就记录下来。
总是现象就是:
spring用到forward("/WEB-INF/jsp/*.jsp")
而forward当然是又要经过web.xml的映射的,
然后,在URL匹配时,
 <url-pattern>/</url-pattern>  不会匹配到*.jsp,不会进入spring的DispatcherServlet类
 <url-pattern>/*</url-pattern> 会匹配*.jsp,导致进入spring的DispatcherServlet类,然后去寻找controller,接着找不到对应的controller所以报错。

试验了一下,改为 <url-pattern>/</url-pattern> 果然就不会报错了,唉,还以为不能解决,为此还换成了velocity作为视图,算了,继续用velocity吧,简单点。

总之,关于web.xml的url映射的小知识:
<url-pattern>/</url-pattern>  会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url
<url-pattern>/*</url-pattern> 会匹配所有url:路径型的和后缀型的url(包括/login,*.jsp,*.js和*.html等)
============================================================================================

译自《Servlet Specification Version 2.4》,转载请注明出处!

把请求映射到Servlet
    在这个章节中描述的映射技术都需要web容器把客户端的请求映射到Servlet。
SRV.11.1 使用URL路径
    当收到一个客户端请求时,web容器决定将请求转交给那个web应用处理。被选择的web应用必须是从前向后匹配的请求URL的最长的上下文路径,匹配的URL部分就是映射到Servlet时的上下文路径。
    Web容器下一步必须使用下面描述的路径映射规则找到处理请求的Servlet。
    用于映射到Servlet的路径是请求的URL去掉上下文路径和路径参数(如http://localhost/myapp/a /a.jsp?msg=hello,上下文路径为/myapp,路径参数为?msg=hello)。按序使用以下URL路径映射规则,第一次匹配成功的规 则将被使用,并且将不会尝试继续匹配:
    1. 容器将试图为请求的路径查找一个精确匹配的Servlet路径。匹配成功则选择该Servlet。
    2. 容器将递归的匹配最长路径前缀,这是通过使用字符'/'做路径分隔符从后往前分隔路径树,一次一个目录,最长的匹配决定了该Servlet被选择。
    3. 如果URL路径最后的部分包含一个扩展名(如.jsp),Servlet容器将尝试匹配一个处理该后缀请求的Servlet,扩展名定义为最后一个'/'后面的部分中字符'.'后的部分。
    4. 如果前面的三个规则都不能匹配到一个Servlet,容器将尝试为请求的资源使用内容服务,如果应用定义了默认的Servlet,则它将被使用。
    容器的匹配过程必须使用大小写敏感的字符串比较。
SRV.11.2 映射详述
在Web应用部署描述符中,下面的语法被用于定义映射:
    • 以'/'开头且以‘/*’结束的字符串用于路径映射。
    • 以'*.'开头的字串串用于扩展名映射。
    • 仅包含'/'的字符串表明对应的Servlet为应用默认的Servlet。在这种情况下Servlet路径是请求的URI去掉上下文路径并且路径信息为null。
    • 所有其它的字符串都被只能用于精确匹配。
SRV.11.2.1 隐式映射
如果容器包含一个内部的JSP容器,则*.jsp扩展名将映射到该容器。允许JSP页面一经请求就执行。这种映射称为隐式映射。如果*.jsp映射被定义成web应用,其优先级高于隐式映射。
一个Servlet容器允许做更多的隐式映射当明确的映射具有高优先级时。例如,*.shtml的隐式映射可以被用于映射成在服务器上包含具体的功能。
SRV.11.2.2 映射例子
思考下面的映射:

Table SRV.11-1 Example Set of Maps
Path Pattern        Servlet
/foo/bar/*             servlet1
/baz/*                   servlet2
/catalog               servlet3
*.bop                    servlet4
紧接着是映射到结果:
Table SRV.11-2 Incoming Paths Applied to Example Maps
Incoming Path Servlet Handling        Request
/foo/bar/index.html                            servlet1
/foo/bar/index.bop                              servlet1
/baz                                                      servlet2
/baz/index.html                                    servlet2
/catalog                                                servlet3
/catalog/index.html                            “default” servlet
/catalog/racecar.bop                          servlet4
/index.bop                                            servlet4
注意例子中的/catalog/index.html和/catalog/racecar.bop并没有映射到/catalog,因为/catalog是一个精确映射。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值