JavaWeb——(web.xml)中的(url-pattern)
一、基本概念
在 web.xml
中,你通过 <servlet-mapping>
来定义一个 Servlet 的映射。<url-pattern>
就是其中的关键子元素,它告诉 Web 容器:“当遇到符合这个模式的请求时,请把它交给那个 Servlet 来处理”。
基本结构:
<web-app><!-- 1. 声明Servlet --><servlet><servlet-name>MyServlet</servlet-name><servlet-class>com.example.MyServlet</servlet-class></servlet><!-- 2. 映射Servlet到URL模式 --><servlet-mapping><servlet-name>MyServlet</servlet-name><url-pattern>/hello</url-pattern> <!-- 这就是我们关注的重点 --></servlet-mapping>
</web-app>
在上面的例子中,任何指向 http://yourdomain.com/yourWebApp/hello
的请求都会被 MyServlet
处理。
二、url-pattern 的四种匹配规则(按优先级排序)
规则优先级从高到低为:精确匹配 > 路径匹配 > 扩展名匹配 > 默认匹配。容器会按照这个顺序查找,使用第一个匹配成功的映射。
1. 精确匹配
模式必须与请求的 URL 完全一致(不包括上下文路径)。
示例:
<url-pattern>/user/info</url-pattern>
<url-pattern>/shop/cart.html</url-pattern>
匹配的 URL:
http://.../yourWebApp/user/info
不匹配的 URL:
/user/info/
,/user/info/123
,/user
2. 路径匹配 (最长路径优先)
使用通配符 *
来表示任意长度的路径。这是最常用的匹配方式。
语法: /path/*
示例:
<url-pattern>/admin/*</url-pattern>
匹配的 URL:
/admin/
/admin/users
/admin/users/add
/admin/old/settings
不匹配的 URL:
/admin
(注意,这里没有尾随的/
)
“最长路径优先”原则:
如果一个 URL 同时匹配多个路径模式,容器会选择最长的那个。
<servlet-mapping><servlet-name>ServletA</servlet-name><url-pattern>/admin/*</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>ServletB</servlet-name><url-pattern>/admin/users/*</url-pattern>
</servlet-mapping>
对于请求 /admin/users/list
,它会匹配到 ServletB
,因为 /admin/users/*
比 /admin/*
更长。
3. 扩展名匹配
匹配特定文件扩展名的请求。
语法: *.扩展名
示例:
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.action</url-pattern>
<url-pattern>*.do</url-pattern>
匹配的 URL:
/index.jsp
/user/login.jsp
/shop/checkout.action
/任何路径/data.do
重要规则:
不能以
/
开头。/*.do
是错误的写法。它不关心路径,只关心结尾的扩展名。
4. 默认匹配 (/ 和 /*)
这是一个特殊且容易混淆的匹配。
<url-pattern>/</url-pattern>
:它匹配所有没有被其他 Servlet 匹配的请求。
它通常被用作 “默认 Servlet” 或用于集成 MVC 框架(如 Spring MVC 的
DispatcherServlet
)。它不会匹配到有扩展名的 URL,比如
.jsp
文件,因为容器通常有一个内置的 Servlet(如JspServlet
)来处理.jsp
请求,它的优先级更高。
<url-pattern>/*</url-pattern>
:(属于路径匹配,优先级高于扩展名匹配)它匹配所有请求,包括
.jsp
、.html
等。如果你将一个 Servlet 映射到
/*
,那么它将拦截所有请求,包括你希望由 JSP 引擎处理的 JSP 页面。这通常会导致你访问index.jsp
时,看到的是 Servlet 输出的内容,而不是被渲染的 JSP 页面。因此,在使用时需要特别小心。