Servlet url-pattern 如何配置
一、url-pattern的匹配规则
1、精确路径匹配
1 2 3 4 5 | 例如: Servlet01 的 url-pattern 配置的是 /* Servlet02 的 url-pattern 配置的是 /hello 这个时候如果浏览器访问 http: //localhost:8080/hello 时,虽然这两个路径都是可以匹配的 但是容器会先优先进行精确路径匹配,发现 /hello 正好被 Servlet02 精确匹配,那么就去调用 Servlet02 ,就不会去理会其他的 Servlet 了. |
2、目录匹配(最长路径优先匹配原则,其实也可以认为是谁的路径相似度更高就匹配谁)
1 2 3 4 5 | 例如: Servlet01 的 url-pattern 配置的是 /aaa/* Servlet02 的 url-pattern 配置的是 /aaa/bbb/* 这个时候如果浏览器访问 http: //localhost:8080/aaa/bbb/hello 时,虽然这两个路径都是可以匹配的 但是容器会进行最长路径匹配,即 Servlet02 的路径更长,描述的更具体,所以会优先匹配上 Servlet02 ,就不会再去匹配 Servlet01 了 |
3、扩展名匹配
1 2 | 例如: 某个 Servlet 的 url-pattern 配置的是 *. do ,如果我访问 http: //localhost:8080/xxx.do 时,这个时候就会根据扩展名进行匹配 |
二、url-pattern 的匹配顺序
1、首先进行精确路径匹配,匹配上了调用相应的 Servlet
2、如果精确路径匹配不上,接着进行目录匹配,如果匹配上了多个,选择路径最长的 Servlet
3、如果目录匹配不上,接着进行扩展名匹配,如果还匹配不上则调用 tomcat 容器中默认的 Servlet
下面我们就结合 SpringMVC 中 DispatcherServlet 的配置案例来说
三、两个web.xml
web 应用需要放在 Tomcat 容器中才能启动,Tomcat 容器内有一个默认的 web.xml 文件(放置在 tomcat 安装目录 /conf/ 下),在自己项目中配置的 web.xml 配置文件都是继承自 Tomcat 中的全局 web.xml 文件并重写其中相应配置,这种继承且重写的关系和子类继承父类并重写相关方法一样,如果子类重写了父类的方法,那么就使用子类的方法,反之就使用父类的方法.像 XML 这种格式化的文件最终会被转换成一个类去保存配置信息,所以理解 Tomcat 中全局 web.xml 文件和项目中 web.xml 文件的关系也可以类比子类重写父类方法的模式.
1、全局 web.xml( tomcat 中的 web.xml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <!--处理静态资源的Servlet--> <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> <!-- The mapping for the default servlet --> <servlet-mapping> <servlet-name> default </servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--处理jsp的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 mappings for the JSP servlet --> <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspx</url-pattern> </servlet-mapping> |
2、项目中 web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 | <servlet> <servlet-name>SpringMVC</servlet-name> <servlet- class >org.springframework.web.servlet.DispatcherServlet</servlet- class > <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMVC.xml</param-value> </init-param> <load-on-startup> 1 </load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> |
根据就近原则,一个请求发送过来,找 web 应用服务器(tomcat)要资源时,首先会尝试和项目中的 web.xml 中进行匹配,如果匹配不上就会去全局的 web.xml 中进行匹配,如果某一个 Servlet 的 <url-pattern> 配置为 /,那么我们就称这个 Servlet 为缺省 Servlet ,凡是在 web.xml 文件中找不到有能和请求匹配的 <url-pattern> ,那么它们的访问请求都交给缺省的Servlet来处理(缺省的 Servlet 作用就是处理别的 Servlet 都不处理的请求).
四、SpringMVC 中 web.xml 前端处理器( DispatcherServelt )的常见配置
不同配置的优先级 /* > *.xxx > / (缺省的 Servlet 排在最后的原因我的理解是:只有所有的 Servlet 都匹配不上时,才会去匹配 / ,所以它的优先级是最低的)
1、前端处理器配置 /*
项目中 web.xml 的 DispatcherServlet 配置了 /* , 由于 /* 的优先级最高,那么所有的请求都会被 DispatcherServlet 处理,等于废弃了 tomcat 中的 web.xml 中的 DefaultServlet 和 JspServlet 的作用
1 2 3 4 5 6 | // /* 的优先级最高,无论什么资源都会被 /* 拦截 1 、访问 http //localhost:8080/index.html 时,任何资源都被前端处理器拦截了,所以 html、css、js 等静态资源也被拦截进了前端处理器,但是在 处理器层(Controller)找不到相应的处理方法处理 index.html 请求,所以会在 Controller 中报错 2 、访问 http //localhost:8080/handle01 时,前端处理器拦截了请求,并把请求传递给了控制器层的 handle01 ,但是返回页面 success.jsp 的请求 也被前端处理器拦截了,不能匹配到 JspServlet,匹配不到 JspServlet 就无法对 jsp 文件进行解析,输出,渲染. |
2、前端处理器配置 /
项目中 web.xml 的 DispatcherServlet 配置了 / ,代表的是缺省的 Servlet ,其它 Servlet 不处理的请求都会交给缺省的 Servlet 来处理
1 2 3 4 5 6 7 8 9 10 11 12 | 访问 http: //localhost:8080/index.html 时,由于我们项目中 DispatcherServlet 配置的是 / ,而 tomcat 中对静态资源进行处理的 DefaultServlet 也是配置的 / ,那么根据就近原则,处理静态资源时会使用我们项目中的 DispatcherServlet ,静态资源被拦截进了 Controller 层,在 Controller 层找不到对应的处理方法,会报错 访问 http: //localhost:8080/index.jsp 时,由于我们项目中 DispatcherServlet 配置的是 / ,而 tomcat 中对 jsp 进行处理的 JspServlet 配置的是 *.jsp 而 *.jsp 的优先级高于 / ,所以 jsp 的处理会交给 tomcat 中的 JspServlet,这个 Servlet 能对 jsp 资源进行解析,输出,渲染 访问 http: //localhost:8080/handle01 时,由于它的路径没有任何 Servlet 能匹配上,那么就交给缺省的 Servlet ,这里有两个缺省 的 Servlet ,分别是 项目中 DispatcherServlet 和 tomcat 中 DefaultServlet ,根据就近原则,会使用项目中 web.xml 中的 DispatcherServlet ,请求被拦截进了前端处理器,前端处理器将请求传递给了控制层的 handle01 处理器,处理完后返回的 success.jsp 被 tomcat的 JspServlet 处理,渲染到页面 |
3、前端处理器配置 *.do 或 *.action
1 2 3 4 | 对于 index.html ,页面正常访问,因为 index.html 没有拦截进前端处理器中,并且 tomcat 中全局 web.xml 中的 DefaultServlet 没有被覆盖, 可以正常的渲染. 对于 index.jsp ,页面正常访问,因为 index.jsp 没有拦截进前端处理器中,并且 tomcat 中的全局 web.xml 中的 JspServlet 没有被覆盖, 可以正常的渲染. |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?