web.xml中servlet匹配优先级探析

 

一. web.xml中配置url-pattern的规则

借鉴

https://www.cnblogs.com/zeling/p/8494844.html

分为四类

1)精确匹配: 匹配确定uri

/index

/index/xyzabc

 2)前缀匹配:

/*

/main/*

3)后缀匹配

*.do

4) / 匹配

   /

以上四种匹配的顺序是

精确匹配>前缀匹配>后缀匹配> /匹配

***注意以下三种前两个合法,第三个不合法***

  /*.do

  /main/*

  /main/*.do

二. 理解tomcat中自带的全局的web.xml和单个应用中web.xml配置的servlet

以下是tomcat中的主要配置,省去了不关注的参数

  <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>


  <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <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>

tomcat中的web.xml, 在每一个webapp中启动的应用都会继承它,  可以在应用自定义的web.xml中选择性覆盖tomcat中配置的,

两个默认servlet,

jspServlet匹配所有*.jsp, 处理jsp相关, 一般不覆盖,

defaultServlet 匹配/,  由优先级可知, *.jsp匹配不到的由/匹配, 且/匹配属于最后的匹配, 前面所有的匹配都没能匹配到则由/匹配,  可以处理静态资源, defaultServlet的作用类似于  else,

三. 针对以上做几组测试验证url匹配

建立index.jsp和index.html,

              

 

 

 以及indexservlet

public class IndexServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json;charset=UTF8");
        PrintWriter writer = resp.getWriter();
        writer.write("welcome");
    }
}

1)web.xml中不配置任何信息

访问结果:

index.html: 可访问

index.jsp:可访问

理解,

默认情况下, index.jsp被默认jsp servlet处理匹配了

index.html, 被default servlet的"/"匹配了, 可以处理静态资源请求,

2)web.xml中如下配置---index servlet 匹配/

<servlet>
    <servlet-name>index</servlet-name>
    <servlet-class>com.bily.springmvc.base.servlet.IndexServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>index</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

访问结果:

index.html: 无法访问原本资源, 而指向了index servlet实现, 

index.jsp:可访问

分析

index.jsp还是被jsp servlet匹配了

由于web.xml中覆盖了default servlet匹配的/路径, 所以 没有被jsp匹配的资源找到/匹配, 即index servlet,  此时的indexServlet匹配 /   ,相当于else,

 

3)indexServet匹配 /*

<servlet>
    <servlet-name>index</servlet-name>
    <servlet-class>com.bily.springmvc.base.servlet.IndexServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>index</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

测试结果

index.html: 指向了index servlet

index.jsp:指向了index servlet

分析

/*匹配属于前缀匹配,优先于jsp servlet的后缀匹配,

  所以index.jsp匹配到了index servlet

  所以index.html同上, 无法被最后的默认的 defaultServlet匹配,

4)index servlet 匹配 /index

<servlet>
    <servlet-name>index</servlet-name>
    <servlet-class>com.bily.springmvc.base.servlet.IndexServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>index</servlet-name>
    <url-pattern>/index</url-pattern>
</servlet-mapping>

测试结果

index.html , index.jsp, /index 都可以正常且正确匹配

分析

此时三个servelt注册

  index 匹配  /index

  jsp 匹配*.jsp

  default 匹配 /

且indexServlet优先级最高,不影响后续匹配

 

总结,

1) 注意tomcat汇总的web.xml和应用中的web.xml中的匹配之间相互覆盖

2) 注意url匹配中的优先级问题, 

3)以上测试,其实回答了为什么 springmvc的dispatcherServlet需要匹配/, 不能匹配/*, 且匹配/ 后静态资源还要重新配置,

原因是, 请求基本分文

jsp请求,静态资源请求,servlet/controller请求,  结合优先级,

a) 如果dispatcherServlet匹配 /*,  属于前缀匹配,  则所有的后缀匹配*.jsp 无法被正确访问, 会被dispatcherServlet处理,

b)早期的dispatcherServlet匹配 *.do形式, 是为了匹配controller, 保留jsp匹配和/的静态资源匹配, 且还不支持静态资源处理, 后来springmvc加强后, 提供了两个配置后, dispatcherServlet也可以处理静态资源了, 

故dispatcherServlet直接匹配/即可,  如果是controller请求,正常处理,  静态资源请求, 开启以上两个配置后可以实现等同于tomcat的静态资源处理,

    <mvc:default-servlet-handler/>
    <mvc:annotation-driven></mvc:annotation-driven>

参考博客(有基于dispatcherServlet映射原理级介绍)

https://www.cnblogs.com/AshOfTime/p/10655014.html

 

posted @ 2020-07-11 14:39  dajgh  阅读(867)  评论(0)    收藏  举报