问题描述  

使用SpringMVC时遇到静态资源无法加载的问题,报404

问题原因

  如果SpringMVC的映射模式采用的是后缀名匹配,如【*.do】或者【*.action】则不会出现该问题,因为静态资源的访问会由tomcat的默认Servlet,即org.apache.catalina.servlets.DefaultServlet,进行处理。

  出现这种问题一般是在web.xml中的对spring的DispatcherServlet采用了如下配置,即url-pattern设置为了“/”(或"/*",这种匹配默认极其恶劣),这样便要求SpringMVC负责处理静态资源请求。

  

<!-- Spring MVC servlet -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
<url-pattern>/</url-pattern>
</servlet-mapping>

  这种情况下浏览器的jsp请求能够成功是以为Tomcat容器默认配置了jsp Servlet,如下。由于url-pattern是“.jsp”,属于扩展名匹配,优先级高于“/”匹配,所以jsp Servlet会被容器调用,不会出现jsp资源无法获取的问题。

  关于Servlet中url-pattern的配置和优先级问题,请参见博文servlet的url-pattern匹配规则

     <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 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使用tomcat容器的默认servlet 处理静态资源请求

在web.xml里添加如下的配置,由于后缀名匹配的优先级高于默认匹配规则(“/”),所以静态资源请求会由DefaultServlet进行处理。

<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping> <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.gif</url-pattern> </servlet-mapping> <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping> <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>

tomcat的default 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-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

在spring的配置文件中添加<mvc:default-servlet-handler/>

<mvc:default-servlet-handler/>

  注意,需要是spring3.0.5以上版本

  该配置会在DispatcherServlet中注册 org.springframework.web.servlet.handler.SimpleUrlHandlerMapping,该类中又注册了访问路径和对应的处理类,如下图:

  /**  ->  org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler

  

  即最终由DefaultServletHttpRequestHandler完成静态资源请求处理。

  这时SpringMVC便具备了处理静态资源请求的能力。

  另外需要注意的是,由于<mvc:default-servlet-handler/> 标签注册了SimpleUrlHandlerMapping类,所以DispatcherServlet便不再默认注册DefaultAnnotationHandlerMapping,也就无法处理RequestMapping等注解。解决方法就是手动在配置文件中配置DefaultAnnotationHandlerMapping bean,或者添加<mvc:annotation-driven/>标签。

在spring的配置文件中添加<mvc:resources mapping="" location="" />

<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/js/**" location="/js/" />

  该标签和<mvc:default-servlet-handler/>类似,也会在DispatcherServlet中注册 org.springframework.web.servlet.handler.SimpleUrlHandlerMapping,不同的是每一条配置都会注册一个SimpleUrlHandlerMapping到DispatcherServlet中,上例会注册三个。

每个SimpleUrlHandlerMapping内部会生成一个映射,如<mvc:resources mapping="/js/**" location="/js/" />对应的SimpleUrlHandlerMapping内部映射为:

"/js/**" -> "ResourceHttpRequestHandler

即最终由ResourceHttpRequestHandler 完成静态资源请求的处理。

另外需要注意的是,使用<mvc:resources mapping="" location="" />后,也需要手动在配置文件中配置DefaultAnnotationHandlerMapping bean,或者添加<mvc:annotation-driven/>标签。

springMVC servlet 静态资源加载的更多相关文章

  1. SpringMvc静态资源加载出错

    使用mvc:resource配置 web.xml配置是rest风格的/ 服务器启动没问题 访问地址是报404 另外用了default-servlet的方法加载,服务器启动没错,jsp页面加载静态资源要 ...

  2. 关于web项目中静态资源加载不了的一些解决思路

    问题的产生: <!--springMVC前端控制器加载--> <servlet> <servlet-name>springmvc</servlet-name& ...

  3. Springboot中jar 重复冲突 导致 静态资源加载问题!

    这个jar 其实在common 中也是存在的  ,当时没注意看,就导入进来了,然后  css js 等一些静态资源全部不能加载!具体原因我没去深挖!后面找个时间深挖下,先填坑!

  4. 【Bug档案01】Spring Boot的控制器+thymeleaf模板 -使用中出现静态资源加载路径不当的问题 -解决时间:3h

    总结 - thymeleaf的模板解析规则不清楚,或者忘了; - 出现bug时,瞎调试, 没有打开NETWORK 进行查看资源的加载情况 - 控制器中的其他代码,可以先注释掉,这样就可以迅速屏蔽掉其他 ...

  5. 关于react打包之后静态资源加载错误的问题

    之前在打包react项目时发现一些问题,打包出来后我的一部分png图标加载不出来,开发者模式发现他们的路径中莫名其妙混入了我在react-router路由中使用<Browserrouter> ...

  6. Springboot:静态资源加载(七)

    WebMvc自动配置: 搜索WebMvcAutoConfiguration自动装配类: 第一种方式通过webjars加载静态资源: https://www.webjars.org(通过maven加载依 ...

  7. spring boot的静态资源加载

    1.spring boot默认资源处理 Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性. spring boot默认加载文 ...

  8. SpringBoot 静态资源 加载位置

    1.配置自定义拦截器 /** * Copyright (C), 2017-2018, XXX有限公司 * FileName: WebConfig * Author: 丶Zh1Guo * Date: 2 ...

  9. spring boot开发 静态资源加载不出来

    spring boot 1.5 版本之前 不拦截静态资源 springboot 2.x版本 拦截静态资源 private static final String[] CLASSPATH_RESOURC ...

随机推荐

  1. 【C++自我精讲】基础系列一 指针与引用

    [C++自我精讲]基础系列一 指针与引用   一 前言   指针.引用.指针与引用区别. 二 指针   变量:代码中常常通过定义变量来申请并命名存储空间,并通过变量的名字来使用这段存储空间. //变量 ...

  2. 使用kettle工具将文本文件的内容插入Linux虚拟机下的mysql表中

    一.      解压kettle包 1.把包拷到Linux系统下 还有mysql的驱动包 2.解压zip后缀的包 输入命令:unzip /software/pdi-ce-7.0.0.0-25.zip ...

  3. 维吉尼亚密码java完整版

    package cn.longxuzi; import org.junit.Test; public class Chi_SquareUtils { private static final ICUt ...

  4. C++ 头文件系列(queue)

    简介 这个头文件定义了两个跟队列有关的类----quque.priority_queue,分别实现的是队列 和 优先队列这两个概念. 但是与这两个类模版与其它类模版(vector.array等)最大的 ...

  5. Ajax beforeSend和complete 方法与防止重复提交

    $.ajax({ beforeSend: function(){ // Handle the beforeSend event }, complete: function(){ // Handle t ...

  6. Jmeter之基本介绍

    初学Jmeter,以下是我常用的功能,总结一下. 1.Thread Group线程组 线程组,即:虚拟用户组

  7. expressJS - 准备活动

    安装 nodeJS 1. package.json 2. CommonJS, AMD, ES6 3. Babel

  8. DOM学习笔记--入门1

    HTML DOM 是关于如何获取.修改.添加或删除 HTML 元素的标准. 首先节点有很多种,不仅仅HTML元素是节点,尤其 要注意文本节点的存在. 根据 W3C 的 HTML DOM 标准,HTML ...

  9. Mysql 5.6 解压版配置方案

    # For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.6/en/server-co ...

  10. 使用Gradle创建java web项目

    什么是Gradle? Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具. 它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML ...