SpringMVC请求静态资源404问题详解

SpringMVC请求静态资源404问题详解_第1张图片
相信上面的这张图片友友们并不陌生吧,特别是在通过 SpringMVC 进行重定向或者请求转发的时候。
比如我们的项目中有一张图片(静态资源):

然后我们通过正确的重定向访问该资源:

@RequestMapping("/img")
public String getImg(){
    return "redirect:/111.png";
}

但我们激动的启动服务器客户端发送请求,就看到了如下惨不忍睹的画面:
SpringMVC请求静态资源404问题详解_第2张图片
那么问题就来了:

  • 为什使用了正确的语法进行重定向却访问失败?
  • 我们请求的静态资源到底是如何处理的?
  • 造成静态资源访问失败的原因是什么?

带着上面的3个问题我们一起来进行分析。⬇️

首先,所谓静态资源指的是如 HTML、CSS、JS、图片等资源。这些静态资源如果想要加载到服务器,我们就需要通过一个默认的 Servlet 叫做 DefaultServlet 来将静态资源加载到服务器(tomcat)中,这样重定向的静态资源才会被找到。

我们可以打开 tomcat 安装目录下的 conf/web.xml 文件,在里面找到 DefaultServlet :
SpringMVC请求静态资源404问题详解_第3张图片

那么我们继续在文件中往下找到 DefaultServlet 的映射信息:

SpringMVC请求静态资源404问题详解_第4张图片

可以看到其映射的 URL 为 / ,看到这里那么问题也就即将得到解决了。

我们再来看看我们配置的前端控制器 DispatcherServlet


<servlet>
    <servlet-name>dispatcherServletservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    
    <init-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:springmvc.xmlparam-value>
    init-param>
    
    <load-on-startup>1load-on-startup>
servlet>

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

仔细观察的你一定发现了,那就是 DefaultServletDispatcherServlet 都是 / 这就涉及到一个优先级问题了。到底是以谁的 / 为准呢?

答案是【就近原则】,项目中配置的 优先级高于 tomcat 实际配置文件中方的

那么也就意味着 DispatcherServlet 配置的 / 会覆盖掉 DefaultServlet 中的 / 。因而导致 DefaultServlet 失效,故无法加载静态资源。这时如果我们直接手动转发或者重定向到静态资源时页面就会出现 404。

SpringMVC请求静态资源404问题详解_第5张图片

其原因是访问静态资源会被当作一个请求而被 DispatcherServlet 拦截,但是找不到映射该请求对应的处理器方法,所以报错。

可是,请求静态资源本就不需要创建处理请求的方法,所以我们需要在 SpringMVC 的配置文件中添加如下配置。⬇️

解决方案:


<mvc:default-servlet-hander/>


<mvc:annotation-driven/>

配置了 标签后将会在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler ,它会对进入 DispatcherServlet 的请求进行筛查,如果发现是没有经过映射的请求,就将该请求交由 Web 应用服务器默认的 DefaultServlet 处理,如果不是静态资源的请求,才由 DispatcherServlet 处理。

好了,本次问题的简单分析就到这里,希望对你有所帮助。

你可能感兴趣的:(报错汇总,servlet,java,tomcat)