springmvc进阶(5):mvc:default-servlet-handler详解

时间:2021-12-23 21:01:36

我们在配置dispatchServlet时配置<url-pattern>/</url-pattern>拦截所有请求,这时候dispatchServlet完全取代了default servlet,将不会再访问容器中原始默认的servlet,而对静态资源的访问就是通过容器默认servlet处理的,故而这时候静态资源将不可访问。

如果想要解决访问静态资源问题,通常会使用默认handler:

<mvc:default-servlet-handler/>
1
看看这个标签的解析类DefaultServletHandlerBeanDefinitionParser的Javadoc是怎么说的吧:

* {@link BeanDefinitionParser} that parses a {@code default-servlet-handler} element to
* register a {@link DefaultServletHttpRequestHandler}. Will also register a
* {@link SimpleUrlHandlerMapping} for mapping resource requests, and a
* {@link HttpRequestHandlerAdapter}.
1
2
3
4
主要是注册了
DefaultServletHttpRequestHandler : 默认的Servlet请求处理器
SimpleUrlHandlerMapping : url - handler映射器
HttpRequestHandlerAdapter : 处理器适配器

静态资源访问是通过uri直接去定位资源,中间不需要繁琐的解析操作,所以这里的映射为 SimpleUrlHandlerMapping 简单直接的映射,映射找到处理器DefaultServletHttpRequestHandler,然后使用HttpRequestHandlerAdapter适配处理器,然后执行。这时候就可以将请求的静态资源返回给客户端。

如果只配置了<mvc:default-servlet-handler/>除了加载上面三个组件,还会加载容器默认加载的组件:

registerBeanNameUrlHandlerMapping(parserContext, source);
registerHttpRequestHandlerAdapter(parserContext, source);
registerSimpleControllerHandlerAdapter(parserContext, source);
1
2
3
对于使用BeanName方式配置的处理器,这时候是可以访问的。但是对于使用@RequestMapping方式配置的处理器这时候是没用的。因为没有相应的HandlerMapping和HandlerAdapter支持注解的使用。
这时候可以使用<mvc:annotation-driven/>配置在容器中注册支持@RequestMapping注解的组件。详细的可看 – mvc:annotation-driven详解

也可以手动在容器中注册:

<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
1
2
3
4
注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter用来支持@RequestMapping注解。

前面说的当DispatcherServlet配置为’/’, 将会覆盖default servlet, 将会处理所有其他Servlet都不处理的访问请求.

所以这里不拦截拦截.jsp, .jspx.的请求, 一定有其他地方拦截了该请求, 但是仔细查找web.xml并没有发现其他的servlet,那一定是在容器中定义的。

果不其然, 在%TOMCAT_HOME%/conf/web.xml中继承过来的JspServlet会处理该请求.

该xml配置了两个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>

<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>
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
这也就是为什么我们直接访问不在WEB-INF的jsp, 可以直接找到并解析的原因了.
---------------------
作者:YellowStar007
来源:CSDN
原文:https://blog.csdn.net/abc997995674/article/details/80513203
版权声明:本文为博主原创文章,转载请附上博文链接!