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

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

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

default-servlet-handler/>

看看这个标签的解析类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}.

主要是注册了
DefaultServletHttpRequestHandler : 默认的Servlet请求处理器
SimpleUrlHandlerMapping : url - handler映射器
HttpRequestHandlerAdapter : 处理器适配器

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

如果只配置了除了加载上面三个组件,还会加载容器默认加载的组件:

registerBeanNameUrlHandlerMapping(parserContext, source);
registerHttpRequestHandlerAdapter(parserContext, source);
registerSimpleControllerHandlerAdapter(parserContext, source);

对于使用BeanName方式配置的处理器,这时候是可以访问的。但是对于使用@RequestMapping方式配置的处理器这时候是没用的。因为没有相应的HandlerMapping和HandlerAdapter支持注解的使用。
这时候可以使用配置在容器中注册支持@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>

注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter用来支持@RequestMapping注解。


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

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

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

该xml配置了两个servlet:

<servlet>
        <servlet-name>defaultservlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServletservlet-class>
        <init-param>
            <param-name>debugparam-name>
            <param-value>0param-value>
        init-param>
        <init-param>
            <param-name>listingsparam-name>
            <param-value>falseparam-value>
        init-param>
        <load-on-startup>1load-on-startup>
    servlet>

    <servlet>
        <servlet-name>jspservlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServletservlet-class>
        <init-param>
            <param-name>forkparam-name>
            <param-value>falseparam-value>
        init-param>
        <init-param>
            <param-name>xpoweredByparam-name>
            <param-value>falseparam-value>
        init-param>
        <load-on-startup>3load-on-startup>
    servlet>

     
       <servlet-mapping>
        <servlet-name>defaultservlet-name>
        <url-pattern>/url-pattern>
    servlet-mapping>

    
    <servlet-mapping>
        <servlet-name>jspservlet-name>
        <url-pattern>*.jspurl-pattern>
        <url-pattern>*.jspxurl-pattern>
    servlet-mapping>

这也就是为什么我们直接访问不在WEB-INF的jsp, 可以直接找到并解析的原因了.

你可能感兴趣的:(springmvc)