servlet映射

一 介绍

在web.xml中通过<servlet/>元素可配置servlet,<servlet-mapping/>元素可以配置servlet对应的地址,如下面所示:

  <!-- 配置DispatcherServlet -->
  <servlet>
  	<servlet-name>dispatcher</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:dispatcher-servlet.xml</param-value>
  	</init-param>
  	<load-on-startup>1</load-on-startup>
  </servlet>
  <!-- Servlet拦截配置 -->
  <servlet-mapping>
  	<servlet-name>dispatcher</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>

下面讲的是<url-pattern/>元素的使用,url-pattern指的是url中位于http://host:port + WebAppName之后部分的匹配模式,比如<url-pattern>/foo</url-pattern>时,此时servlet匹配的url为http://DomainName/WebappName/foo

二 url-pattern设置

一共五种设置方式:

  1. <url-pattern>/*</url-pattern>/*将该web应用的所有的url映射到该servlet上
  2. <url-pattern>/</url-pattern>/ 表示该servlet为默认servlet,只有其他映射匹配不成功时,则传给该servlet处理,比如tomcat就有一个default的默认servlet。
  3. <url-pattern></url-pattern>:元素内容为空,表明当url请求web应用的根目录时,由该servlet处理,也就是将根目录映射到该servlet上。
  4. 前端的控制器的映射:比如上面的dispatcher Servelt就是一个前端控制器,除了上面使用第二种方法外,还可以将该servlet映射到部分url上,比如*.html, *.do, /pages/*, /app/*等等。
  5. 不使用通配符:比如/foo/(目录)、/foo.html(文件)、/foo/foo.jsp等等,则servlet被映射到一个具体的url上

注意

  • 在xml中,之后配置的url会覆盖前面配置的url
  • url必定含有路径,即使url中路径为空,比如url为http://example.com时,即使没有路径,也会默认指向/根路径;也可显式给出根路径:http://example.com/。当路径以/结束时,表示url指向目录,否则指向文件。目录也可以不以/结尾。
  • 不要将url匹配模式url混淆。

三 url解析流程

  1. 当有请求时,会先检测该url是否有对应映射的servlet,如果有,则执行该servlet;否则,匹配不成功,转2
  2. 如果url指向一个文件,则将该文件交给默认servlet处理;否则url指向目录,转3
  3. 查看该目录下是否有welcom-file-list列表指定的文件,如果有,则url重新指向该文件,转1;否则,执行默认servlet,但返回404。

在这里插入图片描述

注意

  • index.jsp不应该被默认servlet处理,而是应该由jsp引擎解析;而jsp引擎是一个servlet,负责解析jsp文件。
  • 只有其他servlet映射不成功时,才会执行默认servlet。默认servlet处理的一般是静态文件,如html、css、js等等。
  • 第2、3步应该都是默认servlet处理的。

四 其他

4.1 welcome-file-list

welcome-file-list列表指定的是该目录下的默认欢迎文件,即url即使访问的是目录,也会尝试返回列表中指定的一个文件。通过将servlet映射到指向目录的url上也能达到同等目的,但是welcome-file-list更为方便。

举个例子:映射一个servlet到http://example.com/webapp/user/这个目录上,即<url-pattern>/user/</url-pattern>,此时也配置了welcom-file-list,按照url解析流程,该servlet匹配该url,执行该servlet,结束。

4.2 springMVC后端控制器映射

前端控制器(DispatcherServlet)拦截的url会根据HandlerMapping配置分发到成功匹配的后端控制器,由该控制器处理请求。因此只有前端控制器拦截到了url,才可能会传给后端控制器。

例子1
前端控制器被映射到/,此时DispatcherServlet为默认servlet。声明一个后端控制器如下:

	@RequestMapping("/user2/")
	public String testUser() {
		...
	}

并且/user2/目录下存在index.jsp。当url为http://example.com/webapp/user2/时,会发生什么?

会执行index.jsp文件。根据url解析流程,通过welcome file list找到index.jsp文件,匹配第三条规则;转1,匹配jsp引擎,执行该引擎(jsp引擎是一个servlet)。

例子2
当DispatcherServlet映射到/*,然后访问http://example.com/webapp/,此时会被DispatcherServlet拦截,不是welcome-file-list指定的文件,因为/*匹配所有url,满足规则一。

但如果启用了spring mvc的DefaultServletHttpRequestHandler,那么DispatcherServlet会将没有被后端控制器匹配的URL交给servlet容器的默认servlet。下面默认启用这项配置。

  • 如果上述url没有被匹配,会被交给默认servlet处理,直接404!因为没有了查找welcom file列表的过程了。
  • 如果url访问http://example.com/webapp/index.html,没有被后端控制器匹配,交给默认servlet处理,那么会返回该网页。
  • 如果URL为http://example.com/webapp/index.jsp,同样也交给了默认servlet处理。此时会如何?会被打印jsp中的源码!!这是因为jsp文件没有被jsp引擎执行,而是被默认servlet执行的。

4.3 tomcat的默认配置

tomcat在全局web.xml文件(在conf目录下)中为所有web应用配置了一个默认servletjsp引擎。全局web.xml相当于添加在每个web应用的web.xml之前,因此可以修改各自应用的web.xml文件来覆盖默认的设置。下面给出conf下web.xml的部分内容:

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
 
    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>
 
    <!-- The mapping for the default servlet -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
 
    <!-- The mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

可以看出,默认servlet的url匹配模式为/,jsp引擎为*.jsp*.jspx


其实全局web.xml中也配置了welcome-file-list列表,因此不用我们自己配置。如:

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

默认servlet用来处理静态文件,而静态文件有很多种类型,返回响应时会在content-type头字段中指定它的MIME类型。

默认servlet如何得知静态文件的MIME类型呢?可以通过文件后缀名得到它的MIME类型。因此在全局web.xml中配置了大量后缀名到MIME类型的映射。内容太多,请自行查看。

参考

url-pattern:https://stackoverflow.com/questions/4140448/difference-between-and-in-servlet-mapping-url-pattern
servlet-mapping的文档介绍:https://docs.oracle.com/cd/E24329_01/web.1211/e21049/web_xml.htm#WBAPP531
welcome file的介绍:https://docs.oracle.com/cd/E24329_01/web.1211/e21049/configurejsp.htm#WBAPP185
参考了最后一行:https://blog.youkuaiyun.com/qq_15237993/article/details/72868089

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值