Difference between / and /* in servlet mapping url pattern

来源:互联网 发布:qq群秒加僵尸软件 编辑:程序博客网 时间:2024/05/17 13:07

使用如下版本Tomcat测试

compile group: 'org.apache.tomcat', name: 'tomcat-catalina', version: '9.0.0.M22'

内容基于stackoverflow的解答,并作出简单解释。


规则:

规则1:精确匹配,使用contextVersion的exactWrappers(例如:`<url-pattern>/hello.jsp</url-pattern>`)规则2:前缀匹配(/*),使用contextVersion的wildcardWrappers规则3:扩展名匹配(*.),使用contextVersion的extensionWrappers(在Tomcat中会默认加入处理jsp与jspx的Servlet)规则4:使用资源文件来处理servlet(welcome-file-list),使用contextVersion的welcomeResources属性,这个属性是个字符串数组规则7:使用默认的servlet(/),使用contextVersion的defaultWrapper

url-pattern /*

<url-pattern>/*</url-pattern>

The /* on a servlet overrides all other servlets, including all servlets provided by the servlet container such as the default servlet and the JSP servlet. Whatever request you fire, it will end up in that servlet.
This is thus a bad URL pattern for servlets.
Usually, you’d like to use /* on a Filter only. It is able to let the request continue to any of the servlets listening on a more specific URL pattern by calling FilterChain#doFilter()

如果url-pattern配置使用/*,则所有的HTTP请求都由该Servlet来处理(精确匹配除外)
所以导致

http://localhost:8080/WebDemo/index.jsphttp://localhost:8080/WebDemo/abc.html

都不能访问(除非你映射了)
当我们使用
@RequestMapping(value = "/test.jsp", method = RequestMethod.GET) 注解,则可以访问http://localhost:8080/WebDemo/test.jsp

所以说上文的overrides 理解为屏蔽比较好。
/* 应该叫做 前缀匹配

形如如下的HTTP请求

http://localhost:8080/WebDemo/test.jsphttp://localhost:8080/WebDemo/test.sbhttp://localhost:8080/WebDemo/test.html

都会由标注了@RequestMapping(value = "/test", method = RequestMethod.GET) 注解的Controller来处理。

这里写图片描述

/对应的详细信息:
StandardEngine[Catalina].StandardHost[localhost].StandardContext[/WebDemo].StandardWrapper[default]
org.apache.catalina.servlets.DefaultServlet
默认的Servlet即为我们在conf/web.xml 里的DefaultServlet
WrapperMappingInfo里的数据代表当前Servlet能够处理哪些请求,虽然列出来这么多但是\* 的优先级最高(精确匹配除外),导致其他的都无法使用。

url-pattern /

<url-pattern>/</url-pattern>

The / doesn’t override any other servlet. It only replaces the servletcontainer’s builtin default servlet for all requests which doesn’t match any other registered servlet. This is normally only invoked on static resources (CSS/JS/image/etc) and directory listings. The servletcontainer’s builtin default servlet is also capable of dealing with HTTP cache requests, media (audio/video) streaming and file download resumes. Usually, you don’t want to override the default servlet as you would otherwise have to take care of all its tasks, which is not exactly trivial (JSF utility library OmniFaces has an open source example). This is thus also a bad URL pattern for servlets. As to why JSP pages doesn’t hit this servlet, it’s because the servletcontainer’s builtin JSP servlet will be invoked, which is already by default mapped on the more specific URL pattern *.jsp.

这里写图片描述

/对应的详细信息:
StandardEngine[Catalina].StandardHost[localhost].StandardContext[/WebDemo].StandardWrapper[WebDemo]
org.springframework.web.servlet.DispatcherServlet
默认的Servlet被替换成我们配置的DispatcherServlet
所以导致静态资源无法访问。
因为有加载了默认的JSP解析器,所以我们项目中编写的JSP文件都是可以访问的。
但是

    @RequestMapping(value = "/test1.jsp", method = RequestMethod.GET)    @ResponseBody    public String test1() {        return "hello";    }

是无法访问的
严重: PWC6117: File “D:\N3verL4nd\Desktop\WebDemo\build\inplaceWebapp\test1.jsp” not found
因为扩展名匹配的优先级别更高。

url-pattern

<url-pattern></url-pattern>

Then there’s also the empty string URL pattern . This will be invoked when the context root is requested. This is different from the <welcome-file> approach that it isn’t invoked when any subfolder is requested. This is most likely the URL pattern you’re actually looking for in case you want a “home page servlet”. I only have to admit that I’d intuitively expect the empty string URL pattern and the slash URL pattern / be defined exactly the other way round, so I can understand that a lot of starters got confused on this. But it is what it is.

Front Controller

In case you actually intend to have a front controller servlet, then you’d best map it on a more specific URL pattern like .html, .do, /pages/, /app/, etc. You can hide away the front controller URL pattern and cover static resources on a common URL pattern like /resources/, /static/, etc with help of a servlet filter. See also How to prevent static resources from being handled by front controller servlet which is mapped on /*. Noted should be that Spring MVC has a builtin static resource servlet, so that’s why you could map its front controller on / if you configure a common URL pattern for static resources in Spring. See also How to handle static content in Spring MVC?

其实说白了在SpringMVC的DispatcherServlet 配置
/*就是匹配所有的内容,但是SpringMVC不一定能处理所有的内容。
/标识的这个Servlet是默认的,当url没有相应的servlet处理时,就用这个默认的。

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-mapping>        <servlet-name>default</servlet-name>        <url-pattern>/</url-pattern></servlet-mapping>
<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><servlet-mapping>        <servlet-name>jsp</servlet-name>        <url-pattern>*.jsp</url-pattern>        <url-pattern>*.jspx</url-pattern></servlet-mapping>
< url-pattern > / </ url-pattern >   不会匹配到*.jsp,即:*.jsp不会进入spring的 DispatcherServlet类 。< url-pattern > /* </ url-pattern > 会匹配*.jsp,会出现返回jsp视图时再次进入spring的DispatcherServlet 类,导致找不到对应的controller所以报404错。 总之,关于web.xml的url映射的小知识:<url-pattern>/</url-pattern>  会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url<url-pattern>/*</url-pattern> 会匹配所有url:路径型的和后缀型的url(包括/login,*.jsp,*.js和*.html等)

https://stackoverflow.com/questions/4140448/difference-between-and-in-servlet-mapping-url-pattern

http://www.cnblogs.com/fangjian0423/p/servletContainer-tomcat-urlPattern.html