Spring MVC 读取静态资源时404错误

    先上总结:前端控制器URL配置/,springmvc中配置<mvc:annotation-driven />,静态资源映射两种两种方式,静态资源路径在webapp根目录下。

    今天调试了两个SSM框架的项目,都出现了同一个问题,静态资源访问不到404错误。看了很多博客和问答,这里总结一下解决方案,记录下采坑记录吧。

    关于静态资源访问不到,最直观的的体现就是你的页面没有任何的样式特效。浏览器控制台也会报出错误,错误代码404。

    这里想起来了一句话,约定优于配置。也就是说,我们在日常开发调试的时候应该具有一些配置习惯。你可以有个性的写业务逻辑,但是对于一些配置问题,还是按照最常用的方法配置为好。

    既然要做静态资源访问,我们首先需要做的事情就是一些约定俗称的配置写法:

  1. 资源路径配置
  2. springmvc.xml中的配置
  3. web.xml中的配置

     一、资源路径配置

    静态资源的路径配置一般情况下是放在webapp或webroot根目录下,WEB-INF下存放的是你项目的页面或者模板。

    像这样:webapp/js、webapp/css、webapp/img..

    二、springmvc.xml中的配置  springmvc版本3.0+ 

    方案一:静态资源映射

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

    方案二:通用配置

<mvc:default-servlet-handler/>  

    把"/**"的url,注册到SimpleUrlHandlerMapping的urlMap中,把对静态资源的访问由HandlerMapping转到org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 处理并返回。

三、web.xml中的配置

    约定配置:<url-pattern>/</url-pattern>使用的是/,而不是/*,如果使用/*,那么请求时可以通过DispatcherServlet转发到相应的Action或者Controller中的,但是返回的内容,如返回的jsp还会再次被拦截,这样导致404错误,即访问不到jsp。所以如果以后发现总是有404错误的时候,别忘了检查一下<url-pattern>/</url-pattern>的配置是否是/*。/表示拦截所有请求。

<!--   Spring MVC Servlet -->  
  
<servlet>  
    <servlet-name>servletName</servlet-name>  
    <servlet-class>  
        org.springframework.web.servlet.DispatcherServlet  
    </servlet-class>  
    <load-on-startup>1</load-on-startup>  
</servlet>  
  
<servlet-mapping>  
    <servlet-name>servletName</servlet-name>   
    <url-pattern>/</url-pattern>  
</servlet-mapping>  

   方案三:激活Tomcat的defaultServlet来处理静态文件

<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>      
<servlet-mapping>          
    <servlet-name>default</servlet-name>         
    <url-pattern>*.css</url-pattern>        
</servlet-mapping>      

 需要注意:

        1. 要配置多个,每种文件配置一个。

        2. 要写在DispatcherServlet的前面, 让defaultServlet先拦截请求,这样请求就不会进入Spring了。
 备注:
    Tomcat, Jetty, JBoss, and GlassFish 自带的默认Servlet的名字 -- "default"
    Google App Engine 自带的 默认Servlet的名字 -- "_ah_default"
    Resin 自带的 默认Servlet的名字 -- "resin-file"
    WebLogic 自带的 默认Servlet的名字  -- "FileServlet"

    WebSphere  自带的 默认Servlet的名字 -- "SimpleFileServlet"

补充说明:多个HandlerMapping的执行顺序问题:
 DefaultAnnotationHandlerMapping的order属性值是:0
<mvc:resources/ >自动注册的 SimpleUrlHandlerMapping的order属性值是: 2147483646
<mvc:default-servlet-handler/>自动注册 的SimpleUrlHandlerMapping 的order属性值是: 2147483647


     spring会先执行order值比较小的。当访问一个a.jpg图片文件时,先通过 DefaultAnnotationHandlerMapping 来找处理器,一定是找不到的,因为我们没有叫a.jpg的Action。然后再按order值升序找,由于最后一个 SimpleUrlHandlerMapping 是匹配 "/**"的,所以一定会匹配上,就可以响应图片。

    最后再说明一下,方案二、方案三 在访问静态资源时,如果有匹配的(近似)总拦截器,就会走拦截器。如果你在拦截中实现权限检查,要注意过滤这些对静态文件的请求。

当然如果你的DispatcherServlet拦截 *.do这样的URL后缀,就不存上述问题了。这样就属于个性化配置了。

jsp文件中获取当前路径URL:

String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  

猜你喜欢

转载自blog.csdn.net/Nerver_77/article/details/81005868