问题描述  

使用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 访问静态资源的更多相关文章

  1. SpringMVC访问静态资源

    SpringMVC访问静态资源 在SpringMVC中常用的就是Controller与View.但是我们常常会需要访问静态资源,如html,js,css,image等. 默认的访问的URL都会被Dis ...

  2. SpringMVC访问静态资源的三种方式(转)

    本文转自:http://www.iigrowing.cn/springmvc_fang_wen_jing_tai_zi_yuan_de_san_zhong_fang_shi.html 如何你的Disp ...

  3. SpringMVC访问静态资源[转]

    1.如果只配置拦截类似于*.do格式的url,则对静态资源的访问是没有问题的,如下: <!-- SpringMVC核心分发器 --> <servlet> <servlet ...

  4. springmvc访问静态资源出现Request method 'GET' not supported

    答案最后.:D 默认的访问的URL都会被DispatcherServlet所拦截. 这里说一下如何配置springmvc访问静态文件. <mvc:default-servlet-handler/ ...

  5. springmvc访问静态资源的springmvc.xml配置

    一. 问题及需求 由于Spring MVC的web.xml文件中关于DispatcherServlet拦截url的配置为"/",拦截了所有的请求,同时*.js,*.jpg等静态资源 ...

  6. $ is not defined与SpringMVC访问静态资源

    编写前台Jquery代码时,遇到谷歌浏览器报错:Uncaught ReferenceError: $ is not defined 意味着Jquery库并没有导入到页面.这是有几种情况需要考虑: 1. ...

  7. SpringMVC访问静态资源的问题。

    在项目中引用css和js文件一直出错,反复修改文件路径始终访问不到.究其原因原来是应该在web.xml 文件中添加访问静态资源的默认servlet. 如下. <servlet-mapping&g ...

  8. 当配置 DispatcherServlet拦截“/”,SpringMVC访问静态资源的三种方式

    如何你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题.如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对*.js,*.jpg ...

  9. SpringMVC访问静态资源的三种方式

    如何你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题.如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对*.js,*.jpg ...

  10. 转转转!SpringMVC访问静态资源的三种方式

    如果你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题.如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对*.js,*.jpg ...

随机推荐

  1. git删除所有提交历史记录

    这种方式是最快最有效的 进项目根目录启动git bash,然后执行这些即可 最后的 git push -f origin master 会失败,直接在idea里push就能成功了 .Checkout ...

  2. linux提权 searchsploit 使用规范

    使用 searchsploit 时,要把整个控制台最大化,这样才能显示完整的漏洞信息. 查看漏洞帮助文件:

  3. setjmp/longjmp 处理异常

    #include <stdio.h> #include <stdlib.h> #include <setjmp.h> jmp_buf jb; void f1() { ...

  4. 一个导致MGR数据混乱Bug的分析和修复

    1.背景 MGR是个好东西,因为他从本质上解决了数据不一致的问题.不光是解决了问题,而且出自名门正派(Oracle的MySQL团队),对品质和后续的维护,我们是可以期待的. 但是在调研的过程中,发现有 ...

  5. elk6.3 centos集群搭建 head插件安装

    版本elk均为6.3+centos7.0 准备工作 官网下载elk6.3的linux环境的压缩包,sftp上传 下载对应的head插件sftp上传到指定目录 tar.gz文件解压 tar -zxvf ...

  6. Loadrunner 性能指标

    https://wenku.baidu.com/view/bf395a1db7360b4c2e3f64ca.html 希望能记住最好记住吧,这个很重要的. qq,979506750多交流

  7. Unity学习笔记(3):一些常用API和应用场景

    Mathf.Lerp(float a,float b,float t)插值函数,当a < b时往a中插入t,以此来实现颜色,声音等渐变效果. GameObject.FindWithTag(str ...

  8. Linux命令对应的英文及整体学习法

    linux命令 注意一下内容收集与互联网,如果觉得有版权问题,请联系. 用Linux命令的时候,如果熟悉对应英文的含义,更有助于理解相应的命令.man: Manual 意思是手册,可以用这个命令查询其 ...

  9. Hyperledger Fabric CA User’s Guide——概述(二)

    概述 下面的图表说明了如何将Hyperledger Fabric CA与总体的Hyperledger Fabric结构相匹配. 有两种方式与一种Hyperledger Fabric CA服务器进行交互 ...

  10. uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)"解决办法

    如果在编译MFC程序的时候出现下列及类似的错误: 1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator ...