Servlet规范当中对映射请求的描述:

在收到客户端请求时,web 容器确定转发到哪一个Web应用。选择的Web应用必须具有最长的上下文路径匹配请求URL的开始。当映射到Servlet时,URL匹配的一部分是上下文。Web 容器接下来必须用下面描述的路径匹配步骤找出servlet来处理请求。用于映射到Servlet的路径是请求对象的请求URL减去上下文和路径参数部分。下面的URL路径映射规则按顺序使用。使用第一个匹配成功的且不会进一步尝试匹配:

  1. 容器将尝试找到一个请求路径到servlet路径的精确匹配。成功匹配则选择该servlet。
  2. 容器将递归地尝试匹配最长路径前缀。这是通过一次一个目录的遍历路径树完成的,使用‘/’字符作为
    路径分隔符。最长匹配确定选择的servlet。
  3. 如果URL最后一部分包含一个扩展名(如.do),servlet容器将视图匹配为扩展名处理请求的Servlet。
    扩展名定义在最后一部分的最后一个‘.’字符之后。
  4. 如果前三个规则都没有产生一个servlet匹配,容器将试图为请求资源提供相关的内容。如果应用中定义
    了一个“default”servlet,它将被使用。许多容器提供了一种隐式的default servlet用于提供内容。
    容器必须使用区分大小写字符串比较匹配。

下面详细描述容器的匹配过程:

  1. 精确路径匹配。例子:比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,也不会去理会其他的 servlet了。
  2. 最长路径匹配。例子:servletA的url-pattern为/test/*,而servletB的url-pattern为/test/a/*,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。
  3. 扩展匹配,如果url最后一段包含扩展,容器将会根据扩展选择合适的servlet。例子:servletA的url-pattern:*.action
  4. 如果前面三条规则都没有找到一个servlet,容器会根据url选择对应的请求资源。如果应用定义了一个default servlet,则容器会将请求丢给default servlet(什么是default servlet?后面会讲)。

根据这个规则表,就能很清楚的知道servlet的匹配过程,所以定义servlet的时候也要考虑url-pattern的写法,以免出错。 对于filter,不会像servlet那样只匹配一个servlet,因为filter的集合是一个链,所以只会有处理的顺序不同,而不会出现只选择一个filter。Filter的处理顺序和filter-mapping在web.xml中定义的顺序相同。

url-pattern详解,在web.xml文件中,以下语法用于定义映射:

  1. 以”/’开头和以”/*”结尾的是用来做路径映射的。 (对应于第2条匹配规则)
  2. 以前缀”*.”开头的是用来做扩展映射的。 (对应于第3条匹配规则)
  3. “/” 是用来定义default servlet映射的。 (对应于第4条匹配规则)
  4. 剩下的都是用来定义详细映射的。比如: /aa/bb/cc.action (对应于第1条匹配规则)

所以,为什么定义”/*.action”这样一个看起来很正常的匹配会错?因为这个匹配即属于路径映射,也属于扩展映射,导致容器无法判断。

下面详细讲述对于上面比配情况Servlet API当中方法的值情况:

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

记住下面三点:

  1. Request URI = context path + servlet path + path info.
  2. Context paths 和 servlet paths 以 '/' 开始,但是不以'/'结尾.
  3. HttpServletRequest 提供3个方法 getContextPath(),getServletPath() 和getPathInfo() 来分别获取 context path, servlet path,  path info。

识别servlet路径 :

为了匹配一个servlet请求URI,servlet容器遵循一个简单的算法。 一旦确定了上下文路径,如果有的话,它会评估该请求URI的其余部分与在部署描述符中指定的servlet映射,按下列顺序。如果它找到一个匹配在任何步骤,它不采取下一个步骤。

  1. 精确路径匹配(上面匹配的第一条规则):在这种情况下,getPathInfo()为空。
  2. 最长路径匹配(上面匹配的第二条规则): 如果有一个匹配,请求URI的匹配部分是getServletPath() 结果,其余部分是getPathInfo()。
  3. 扩展匹配(上面匹配的第三条规则): 在这种情况下,完整的请求URI是getServletPath()和getPathInfo()为空。
  4. 默认servlet匹配(上面匹配的第四条规则): 如果没有默认的servlet,它会发送未找到指示的servlet的错误消息。

通过例子来熟悉一下:

<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

映射请求到Servlet的更多相关文章

  1. 用@RequestMapping映射请求

    DispatcherServlet接受一个web请求之后,将请求发送给@Controller注解声明的不同控制器类. 这个调度过程依赖控制器类及其处理程序方法中声明的各种@RequestMapping ...

  2. @RequestMapping映射请求,@PathVariable,@RequestParam,@RequestHeader的使用

    1.@RequestMapping Spring MVC 使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求,在控制器的类定义及方法定义处都可标注. @RequestMa ...

  3. SpringMVC——映射请求参数

    Spring MVC 通过分析处理方法的签名,将 HTTP 请求信息绑定到处理方法的相应人参中. @PathVariable @RequestParam @RequestHeader 等) Sprin ...

  4. SpringMVC学习 -- 使用 @RequestMapping 映射请求

    在控制器的类定义及方法出定义出都可以标注 @RequestMapping: 类定义处:提供初步的请求映射信息.相对于 Web 应用的根目录. 方法定义出:提供进一步的细分映射信息.相对于类定义处的 U ...

  5. Spring MVC的映射请求

    一.SpringMVC常用注解 @Controller 声明Action组件 @Service    声明Service组件    @Service("myMovieLister" ...

  6. SpringMVC听课笔记(四:映射请求参数 & 请求头)

    1.请求参数 @RequestParam  来映射请求参数  http://localhost:8080/springmvc-1/springmvc/testRequestParam?username ...

  7. 【SpringMVC】SpringMVC系列6之@CookieValue 映射请求Cookie 值

      6.@CookieValue 映射请求Cookie 值 6.1.示例 @CookieValue 可让处理方法入参绑定某个 Cookie 值,示例如下:     

  8. 【SpringMVC】SpringMVC系列5之@RequestHeader 映射请求头属性值

    5.@RequestHeader 映射请求头属性值 5.1.概述 请求头包含了若干个属性,服务器可据此获知客户端的信息,通过 @RequestHeader 即可将请求头中的属性值绑定到处理方法的入参中 ...

  9. 【SpringMVC】SpringMVC系列4之@RequestParam 映射请求参数值

    4.@RequestParam 映射请求参数值 4.1.概述     Spring MVC 通过分析处理方法的签名,将 HTTP 请求信息绑定到处理方法的相应人参中.Spring MVC 对控制器处理 ...

随机推荐

  1. csu 1503: 点弧之间的距离-湖南省第十届大学生计算机程序设计大赛

    这是--比量p并用交点连接中心不上弧.在于:它至p距离.是不是p与端点之间的最短距离 #include<iostream> #include<map> #include< ...

  2. [CLR via C#]1.5 本地代码生成器:NGen.exe

    原文:[CLR via C#]1.5 本地代码生成器:NGen.exe 1. NGen.exe工具,可以在一个程序安装到用户计算机时,将IL代码编译成为本地代码.由于代码在安装时已经编译好,所以CLR ...

  3. MapReduce的InputFormat学习过程

    昨天,经过几个小时的学习.该MapReduce学习的某一位的方法的第一阶段.即当大多数文件的开头的Data至key-value制图.那是,InputFormat的过程.虽说过程不是非常难,可是也存在非 ...

  4. 砸金蛋:jQuery+PHP实现的砸金蛋中奖程序

    原文 砸金蛋:jQuery+PHP实现的砸金蛋中奖程序 砸金蛋被广泛应用于庆典活动.商家促销.电视娱乐等场合,它的趣味.悬念能迅速活跃现场气氛.同样,我们也可以将砸金蛋应用到WEB网站上,用于开展线上 ...

  5. javascript 验证 yyyy-MM-dd HH:mm:ss 的正则表达式

    原文:javascript 验证 yyyy-MM-dd HH:mm:ss 的正则表达式 ^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13 ...

  6. 浅谈 js 字符串 search 方法

    原文:浅谈 js 字符串 search 方法 这是一个很久以前的事情了,好像是安心兄弟在学习js的时候做的练习.具体记不清了,今天就来简单分析下 search 究竟是什么用的. 从字面意思理解,一个是 ...

  7. 那些必须要知道的Javascript

    原文:那些必须要知道的Javascript JavaScript是前端必备,而这其中的精髓也太多太多,最近在温习的时候发现有些东西比较容易忽略,这里记录一下,一方面是希望自己在平时应用的时候能够得心应 ...

  8. nginx 查看并发连接数

    这里仅仅说一下用命令查看(也可配置页面) 通过查tcp连接数 1.netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]} ...

  9. 快速构建Windows 8风格应用11-语义缩放

    原文:快速构建Windows 8风格应用11-语义缩放 本篇博文主要介绍为什么需要语义缩放.什么是语义缩放.如何构建语义缩放. 为什么需要语义缩放 如果用过Windows 8系统的开发者都知道在Win ...

  10. SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比

    原文:SQL点滴10-使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比 今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章 ...