web.xml配置文件中的servlet和servlet-mapping

转自:https://blog.csdn.net/u013815649/article/details/50435819

写了好多小项目后也没弄明白<url-pattern>的真正意义,写跳转的时候也是跳的三心二意的,今天查了一下web.xml的详细配置,看了看servlet-mapping的讲解,豁然开朗,做了做小实验,原来是这样,捂脸。下面把看到的文章的servlet片段摘抄过来,先附上链接(http://blog.csdn.net/believejava/article/details/43229361)(作者如有意见,私信删文);


容器的 Context 对象对请求路径 (URL) 做出处理,去掉请求 URL 的上下文路径后,按路径映射规则和 Servlet 映射路径( <url- pattern> )做匹配,如果匹配成功,则调用这个 Servlet 处理请求。

servlet容器对url的匹配过程: 

当一个请求发送到servlet容器的时候,容器先会将请求的url减去当前应用上下文的路径作为servlet的映射url,比如我访问的是http://localhost/test/aaa.html,我的应用上下文是test,容器会将http://localhost/test去掉,剩下的/aaa.html部分拿来做servlet的映射匹配。这个映射匹配过程是有顺序的,而且当有一个servlet匹配成功以后,就不会去理会剩下的servlet了(filter不同,后文会提到)。其匹配规则和顺序如下: 

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中定义的顺序相同。


<servlet></servlet>

 
[html]  view plain copy
  1. <!--****************************servlet配置******************************-->  
  2. <!-- Spring view分发器  对所有的请求都由business对应的类来控制转发 -->  
  3. <servlet>  
  4.     <servlet-name>business</servlet-name>  
  5.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  6.     <init-param>  
  7.       <param-name>publishContext</param-name>  
  8.       <param-value>false</param-value>  
  9.     </init-param>  
  10.     <load-on-startup>1</load-on-startup>  
  11. </servlet>  
  12. <!-- 用户登出 -->  
  13. <servlet>  
  14.     <servlet-name>LogOutServlet</servlet-name>  
  15.     <servlet-class>com.yonyou.mcloud.cas.web.servlet.LogOutServlet</servlet-class>  
  16.     <init-param>  
  17.       <param-name>serverLogoutUrl</param-name>  
  18.       <param-value>https://dev.yonyou.com:443/sso-server/logout</param-value>  
  19.     </init-param>  
  20.     <init-param>  
  21.       <param-name>serverName</param-name>  
  22.       <param-value>http://10.1.215.40:80/business/</param-value>  
  23.     </init-param>  
  24. </servlet>  
  25. <!--****************************servlet映射关系配置*************************-->  
  26. <servlet-mapping>  
  27.     <servlet-name>LogOutServlet</servlet-name>  
  28.     <url-pattern>/logout</url-pattern>  
  29. </servlet-mapping>  
  30. <servlet-mapping>  
  31.     <servlet-name>business</servlet-name>  
  32.     <url-pattern>/</url-pattern>  
  33. </servlet-mapping>  
  1. Servlet介绍

Servlet通常称为服务器端小程序,是运行在服务器端的程序,用于处理及响应客户的请求。Servlet是个特殊的java类,继承于HttpServlet。客户端通常只有GETPOST两种请求方式,Servlet为了响应则两种请求,必须重写doGet()doPost()方法。大部分时候,Servlet对于所有的请求响应都是完全一样的,此时只需要重写service()方法即可响应客户端的所有请求

另外HttpServlet有两个方法

  • init(ServletConfig config):创建Servlet实例时,调用该方法的初始化Servlet资源
  • destroy():销毁Servlet实例时,自动调用该方法的回收资源。

通常无需重写init()destroy()两个方法,除非需要在初始化Servlet时,完成某些资源初始化的方法,才考虑重写init()方法,如果重写了init()方法,应在重写该方法的第一行调用super.init(config),该方法将调用HttpServletinit()方法。如果需要在销毁Servlet之前,先完成某些资源的回收,比如关闭数据库连接,才需要重写destory方法()

Servlet的生命周期:

创建Servlet实例有两个时机:

  • 客户端第一次请求某个Servlet时,系统创建该Servlet的实例,大部分Servlet都是这种Servlet
  • Web应用启动时立即创建Servlet实例,即load-on-start Servlet

每个Servlet的运行都遵循如下生命周期:

  1. 创建Servlet实例
  2. Web容器调用Servletinit()方法,对Servlet进行初始化。
  3. Servlet初始化后,将一直存在于容器中,用于响应客户端请求,如果客户端发送GET请求,容器调用ServletdoGet()方法处理并响应请求;如果客户端发送POST请求,容器调用ServletdoPost()方法处理并响应请求。或者统一使用service()方法处理来响应用户请求。
  4. Web容器决定销毁Servlet时,先调用Servletdestory()方法,通常在关闭Web应用时销毁Servlet实例
  1. Servlet配置:

为了让Servlet能响应用户请求,还必须将Servlet配置在web应用中,配置Servlet需要修改web.xml文件

Servlet3.0开始,配置Servlet有两种方式:

  • Servlet类中使用@WebServlet Annotation进行配置。
  • web.xml文件中进行配置。

我们用web.xml文件来配置Servlet,需要配置<servlet><servlet-mapping>

<servlet>用来声明一个Servlet<icon><display-name><description>元素的用法和<filter>的用法相同。<init-param>元素与<context-param>元素具有相同的元素描述符,可以使用<init-param>子元素将初始化参数名和参数值传递给Servlet,访问Servlet配置参数通过ServletConfig对象来完成,ServletConfig提供如下方法:

java.lang.String.getInitParameter(java.lang.String name):用于获取初始化参数

ServletConfig获取配置参数的方法和ServletContext获取配置参数的方法完全一样,只是ServletConfig是取得当前Servlet的配置参数,而ServletContext是获取整个Web应用的配置参数。

  1. <description><display-name><icon>
  • <description>:为Servlet指定一个文本描述。
  • <display-name>:为Servlet提供一个简短的名字被某些工具显示。
  • <icon>:为Servlet指定一个图标,在图形管理工具中表示该Servlet
  1. <servlet-name><servlet-class><jsp-file>元素

<servlet>必须含有<servlet-name><servlet-class>,或者<servlet-name><jsp-file> 描述如下:

  • <servlet-name>用来定义servlet的名称,该名称在整个应用中必须是惟一的
  • <servlet-class>用来指定servlet的完全限定的名称。
  • <jsp-file>用来指定应用中JSP文件的完整路径。这个完整路径必须由/开始。
  1. <load-on-startup>

如果load-on-startup元素存在,而且也指定了jsp-file元素,则JSP文件会被重新编译成Servlet,同时产生的Servlet也被载入内存。<load-on-startup>的内容可以为空,或者是一个整数。这个值表示由Web容器载入内存的顺序。

举个例子:如果有两个Servlet元素都含有<load-on-startup>子元素,则<load-on-startup>子元素值较小的Servlet将先被加载。如果<load-on-startup>子元素值为空或负值,则由Web容器决定什么时候加载Servlet。如果两个Servlet<load-on-startup>子元素值相同,则由Web容器决定先加载哪一个Servlet

<load-on-startup>1</load-on-startup>表示启动容器时,初始化Servlet

  1. <servlet-mapping>

<servlet-mapping>含有<servlet-name><url-pattern>

  • <servlet-name>Servlet的名字,唯一性和一致性,与<servlet>元素中声明的名字一致。
  • <url-pattern>:指定相对于ServletURL的路径。该路径相对于web应用程序上下文的根路径。<servlet-mapping>URL模式映射到某个Servlet,即该Servlet处理的URL
  1. 加载Servlet的过程 

容器的Context对象对请求路径(URL)做出处理,去掉请求URL的上下文路径后,按路径映射规则和Servlet映射路径(<url- pattern>)做匹配,如果匹配成功,则调用这个Servlet处理请求。

  1. DispatcherServletweb.xml中的配置:
 
[html]  view plain copy
  1. <!-- Spring view分发器  对所有的请求都由business对应的类来控制转发 -->  
  2. <servlet>  
  3.     <servlet-name>business</servlet-name>  
  4.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  5.     <init-param>  
  6.       <param-name>publishContext</param-name>  
  7.       <param-value>false</param-value>  
  8.     </init-param>  
  9.     <load-on-startup>1</load-on-startup>  
  10. </servlet>  
配置Spring MVC,指定处理请求的Servlet,有两种方式:
l  默认查找MVC配置文件的地址是:/WEB-INF/${servletName}-servlet.xml
l  可以通过配置修改MVC配置文件的位置,需要在配置DispatcherServlet时指定MVC配置文件的位置。
    我们在平台项目两个工程中分别使用了不同的配置方式,介绍如下:
我们在business-client工程中按照默认方式查找MVC的配置文件,配置文件目录为: /WEB-INF/business-servlet.xml。工程目录结构如下所示:
我们在public-base-server工程中,通过第2种方式进行配置,把spring-servlet.xml放到src/main/resources/config/spring-servlet.xml,则需要在配置DispatcherServlet时指定<init-param>标签。具体代码如下:
 
[html]  view plain copy
  1. <servlet>  
  2.     <servlet-name>spring</servlet-name>  
  3.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.       <init-param>  
  5.               <param-name>publishContext</param-name>  
  6.               <param-value>false</param-value>  
  7. </init-param>  
  8.  <init-param>    
  9.                      <param-name>contextConfigLocation</param-name>    
  10.                     <param-value>classpath:config/spring-servlet.xml</param-value>    
  11.            </init-param>   
  12.      <load-on-startup>1</load-on-startup>  
  13. </servlet>  
工程目录结构如下:
其中,classpathweb项目的类路径,可以理解为classes下面。因为无论这些配置文件放在哪,编译之后如果没有特殊情况的话都直接在classes下面。jar包的话虽然放在lib文件夹里,但实际上那些类可以直接引用,比如:com.test.ABC,仿佛也在classes下面一样。
在我们的工程里,经过验证,maven工程这两个
路径经过编译后生成的文件都位于classes目录下,即这两个路径相当于类路径,在下面创建config文件夹(folder),然后创建自定义的xml配置文件即可。
classpathclasspath*区别:
同名资源存在时,classpath只从第一个符合条件的classpath中加载资源,而classpath*会从所有的classpath中加载符合条件的资源。classpath*,需要遍历所有的classpath,效率肯定比不上classpath,因此在项目设计的初期就尽量规划好资源文件所在的路径,避免使用classpath*来加载。
  1. ContextLoaderListenerDispatcherServlet初始化上下文关系和区别:


从上图可以看出,ContextLoaderListener初始化的上下文加载的Bean是对于整个应用程序共享的,一般如:DAO层、ServiceBeanDispatcherServlet初始化的上下文加载的Bean是只对Spring MVC有效的Bean,如:ControllerHandlerMappingHandlerAdapter等,该初始化上下文只加载Web相关组件。
注意:用户可以配置多个DispatcherServlet来分别处理不同的url请求,每个DispatcherServlet上下文都对应一个自己的子Spring容器,他们都拥有相同的父Spring容器(业务层,持久(daobean所在的容器)。


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值