SpringMVC处理静态资源的方式,你真的知道吗?

目录

servlet中的静态资源和jsp

如何让springMVC处理所有请求

解决方案

方案一:

方案二:

总结


servlet中的静态资源和jsp

回想一下,我们之前学servlet的时候,静态资源和jsp是被谁处理的?

不知大家是否注意了一个问题,我们将 web 项目发布到 tomcat 后,可以直接访问 jsp 后缀的文件,或者直接访问项目中的静态资源(js/css/图片之类的文件),只要路径写的没有问题,都可以正常在浏览器中显示,大家是否思考过,是谁在处理这个请求呢?

tomcat 是一个 servlet 容器,servlet 容器中通常有 servlet 来处理各种请求,那么当我们访问静态资源或者 jsp 的时候,当然也是由 servlet 来处理这些请求的,但是我们并没有在 web.xml 中配置由哪个 servlet 来处理这些请求啊,这是因为 tomcat 中自动帮我们配置了一些默认的 servlet 来处理这类的请求。

tomcat 的安装目录中有个 web.xml 文件,位于(apache-tomcat-9.0.46\conf\web.xml),这个文件相当于对发布到 tomcat 中的所有 web 项目的默认配置,我们来看一下这个文件,有几个重要的 servlet 配置信息,这些 servlet 可以用来处理 jsp 后置的文件或者静态资源,抽取部分配置如下

<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>
   <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>

 

配置中主要定义了 2 个 servlet

  1. JspServlet 用来处理 jsp 文件

  2. DefaultServlet 会处理/开头的请求,这里重点说下这个 servlet 的处理逻辑,它会处理所有其他 servlet 不匹配的请求,当一个请求过来之后,会先去匹配其他的 servlet,当找不到匹配的 servlet 的时候,才会走 DefaultServlet

  3. 我们可以在项目中的 web.xml 中对 tomcat/config/web.xml 中的配置进行覆盖,即项目中的 web.xml 相对于 tomcat 中的 web.xml 有更高的优先级。

如何让springMVC处理所有请求

如果我们想让 springmvc 来处理所有的请求,怎么做呢?只需修改 web.xml 中的配置,将 springmvc 这个 servlet 的 url-pattern 的值设置为/就可以了,此时所有的请求都会被 springmvc 处理,即所有的请求都会被DispatcherServlet处理。

<servlet>
   <servlet-name>DispatcherServlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
   <servlet-name>DispatcherServlet</servlet-name>
   <url-pattern>/</url-pattern><!--地址缺省,表示此项目下的任何请求都会经过此servlet-->
 </servlet-mapping>

当我们配置了上面的DispatcherServlet来处理所有请求的时候,我们此时去访问静态资源,发现居然404了,上面原因???

因为我们配置了DispatcherServlet来处理所有请求,所以我们静态资源的请求被 DispatcherServlet 接收了,但是这个 servlet 默认情况下并没有处理静态资源的能力,即找不到请求的资源,所以才会报 404。

解决方案

方案一:

在springmvc的配置文件中加上:

<mvc:annotation-driven/>
<mvc:default-servlet-handler/>

这里说一下原理

1、加入配置后,框架会创建DefaultServletHttpRequestHandler对象,当我们访问静态资源时,DispatcherServlet发现自己处理不了,然后会将请转发给 tomcat 的 default 这个 servlet 处理,所以静态资源就可以正常访问了

2、注意:配置中的第 1 行也必须加上,如果不加上,@RequestMapping 的请求就无法处理了

3、这种用法有个前提是,web 容器中需要有 default 这个 servlet,且这个 servlet 可以处理静态资源

方案二:

从 spring3.0 版本后,spring 定义了专门处理静态资源访问请求的处理器ResourceHttpRequestHandler,并且添加了标签,用来处理静态资源无法访问的问题。

需要在 springmvc 配置文件中添加如下配置

<mvc:annotation-driven/>
<mvc:resources mapping="/imgs/**" location="/static/imgs/"/>
<mvc:resources mapping="/css/**" location="/static/css/"/>
<mvc:resources mapping="/js/**" location="/static/js/"/>
  • mvc:resource 标签用来指定请求的静态资源的 url 和本地地址的映射关系

  • mapping:用来指定请求的地址的,比如/imgs/**:可以匹配任何以 imgs 开头的 url,如:/imgs/1.jpg、/imgs/2.jpg、/imgs/order/3.jpg

  • location:用来指定静态资源所在项目中的目录

  • 注意:配置中的第 1 行也必须加上,如果不加上,@RequestMapping 的请求就无法处理了

  • 这种用法不依赖于 web 容器,所以比第一种方案要好一些,也建议大家用这种方案。

总结

  • tomcat 默认能够处理 jsp 和静态资源,是因为 tomcat 中默认有 2 个 servlet:default 和 jsp

  • 到此我们已经知道如何让 springmvc 来处理所有请求了,只需要在 web.xml 中调整一下 url-pattern 的值为/就可以了

  • 默认情况下,springmvc 无法处理静态资源,本文介绍了 2 种方式,大家可以回头在再去看看,第一种需要依赖于 web 容器中的 default 这个 servlet,使用上面对 web 容器有依赖作用;而第 2 种方式是 springmvc 推荐的方式,更好一些,对 web 容器没有依赖

  • 不管用那种方式,都不要忘记了这个注解,否则咱们自定义的 controller 中的@RequestMapping 就无效了

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰魄雕狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值