欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【SpringMVC问题】springmvc添加mvc:default-servlet-handler后,静态资源可以访问,controller不能访问

程序员文章站 2022-03-21 11:25:55
问题springmvc添加或者后,静态资源可以访问,Controller不能访问,删掉后才能访问controller具体配置文件 ...

文章目录

问题

springmvc添加<mvc:default-servlet-handler/>或者<mvc:resources mapping="/img/**" location="/img/"/>后,静态资源可以访问,Controller不能访问,删掉<mvc:default-servlet-handler/>后才能访问controller
具体配置文件

 <context:component-scan base-package="com.cw">
        <!-- 只加载使用@Controller标注的bean -->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--
        核心控制器拦截的是所有请求,需要对静态资源请求进行放行,通过配置放行资源实现
    -->
    <!--放行指定类型静态资源配置方式-->
    <!--<mvc:resources mapping="/img/**" location="/img/"/>
    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/css/**" location="/css/"/>-->

    <!--SpringMVC提供的通用资源放行方式,可以放行所有普通资源-->
    <mvc:default-servlet-handler/>

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

<mvc:default-servlet-handler/>

该标签的xsd文档说明如下:

/*配置一个handler通过转发到servlet容器的默认servlet来处理静态资源*/
Configures a handler for serving static resources by forwarding to the Servlet container's default Servlet. 

/*使用该handler允许DispatcherServlet 的url-patter 为'/',同时仍然使用servlet让其去处理静态资源*/
Use of this handler allows using a "/" mapping with the DispatcherServlet while still utilizing the Servlet container to serve static resources. 

/*该handler将会转发所有的请求到默认serlvet*/
This handler will forward all requests to the default Servlet. 

/*所以,在所有的URL HandlerMappings中,该handler对应的mapping应该留置最后!*/
Therefore it is important that it remains last in the order of all other URL HandlerMappings. 

/*你可以使用两种方式去保证你的handlermapping 的order属性值小于DefaultServletHttpRequestHandler  对应的handlermapping的order属性值:使用<mvc:annotation-driven/>标签或者手动配置HandlerMapping实例并设置其order属性值*/
That will be the case if you use the "annotation-driven" element 
or alternatively if you are setting up your customized HandlerMapping instance 

be sure to set its "order" property to a value lower 

than that of the DefaultServletHttpRequestHandler, which is Integer.MAX_VALUE.

【SpringMVC问题】springmvc添加mvc:default-servlet-handler后,静态资源可以访问,controller不能访问

default-servlet-handler将在SpringMVC上下文中定义一个DefaultServletHttpRequestHandler

DefaultServletHttpRequestHandler的javadoc如下:

/**
 * An {@link HttpRequestHandler} for serving static files using the Servlet container's "default" Servlet.
 *
 * <p>This handler is intended to be used with a "/*" mapping when the
 * {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet}
 * is mapped to "/", thus  overriding the Servlet container's default handling of static resources.
 * The mapping to this handler should generally be ordered as the last in the chain so that it will
 * only execute when no other more specific mappings (i.e., to controllers) can be matched.
 *
 * <p>Requests are handled by forwarding through the {@link RequestDispatcher} obtained via the
 * name specified through the {@link #setDefaultServletName "defaultServletName" property}.
 * In most cases, the {@code defaultServletName} does not need to be set explicitly, as the
 * handler checks at initialization time for the presence of the default Servlet of well-known
 * containers such as Tomcat, Jetty, Resin, WebLogic and WebSphere. However, when running in a
 * container where the default Servlet's name is not known, or where it has been customized
 * via server configuration, the  {@code defaultServletName} will need to be set explicitly.
 *
 * @author Jeremy Grelle
 * @author Juergen Hoeller
 * @since 3.0.4
 */

翻译如下

/*使用servlet容器的默认servlet处理静态资源*/
An {@link HttpRequestHandler} for serving static files using the Servlet container's "default" Servlet.

/*当DispatcherServlet url-pattern为"/"时,该handler将会使用"/*"去匹配请求路径;因此,重置了servlet容器对静态资源的默认处理*/
This handler is intended to be used with a "/*" mapping 
when the {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet} is mapped to "/", 
thus overriding the Servlet container's default handling of static resources.

/*匹配该handler的mapping 应该是最后到达,当没有其他mapping可以处理请求时才会执行该handler匹配的mapping。*/
The mapping to this handler should generally be ordered as the last in the chain 
so that it will only execute when no other more specific mappings (i.e., to controllers) can be matched. 

即,当DispatcherServlet url-pattern为"/“时,该handler将会使用”/*"去匹配请求路径。

参考servlet的url-pattern规则可知/*可以拦截一切请求。因为/将servlet定义为默认serlvet,在没有精确匹配servlet出现前,/*将拥有最高的优先级

这是很严重的,/*可以拦截路径和资源型的请求,并转发到默认的serlvet

也就是说,静态资源此时可以由默认default servlet进行处理,但是default servlet不能处理你的业务请求(mapping)

所以,需要保证该handler对应的handler mapping在执行顺序中为最后

解决办法

在配置文件中添加以下配置项

<mvc:annotation-driven />

annotation-driven 配置的作用如下:

  1. 主要是注册了 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter bean,存储了请求url到Controller方法的映射关系
  2. 注册了异常处理器

RequestMappingHandlerMapping:HandlerMapping的实现类,它处理的是@RequestMapping注解,并将其注册到映射表中,即url对应的Controller的方法
RequestMappingHandlerAdapter:HandlerAdapter的实现类,它是处理请求的适配器,就是确定调用哪个Controller的 哪个方法

Spring MVC 中如果配置了 <mvc:annotation-driven> ,则所有的 Controller 就会被解析,所以相应的请求就会被 Controller 处理,因此这个配置至关重要。当请求没有匹配到处理类(其中包括没有配置 <mvc:annotation-driven> 或者 访问的是静态资源文件)时,就会去找 <mvc:default-servlet-handler> (处理静态资源文件)配置的 DefaultServletHttpRequestHandler 默认处理器处理了

<mvc:annotation-driven />:使用默认的servlet来响应静态文件,建议放在开始;
<mvc:default-servlet-handler/>:放在注解处理映射器的后面,可以直接放在文件最后面

这样就不会出现<mvc:default-servlet-handler/>导致controller失效

本文地址:https://blog.csdn.net/qq_26838315/article/details/112572747

相关标签: 后端 Java