Spring MVC 教程-如何集成静态资源?

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

1、本文内容

  • 静态资源 & jsp 是被谁处理的?
  • 如何让springmvc处理所有请求?
  • springmvc如何处理静态资源?
  • springmvc处理静态资源的2种方案、区别、原理详解
  • 领取后端必备的200本书籍

2、静态资源 & 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>
    	<load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet>
    	<servlet-name>jsp</servlet-name>
    	<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    	<load-on-startup>3</load-on-startup>
    </servlet>
    
    <servlet-mapping>
    	<servlet-name>default</servlet-name>
    	<url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <servlet-mapping>
    	<servlet-name>jsp</servlet-name>
    	<url-pattern>*.jsp</url-pattern>
    	<url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

配置中主要定义了2个servlet

  1. JspServlet用来处理jsp文件
  2. DefaultServlet会处理/开头的请求,这里重点说下这个servlet的处理逻辑,它会处理所有其他servlet不匹配的请求,当一个请求过来之后,会先去匹配其他的servlet,当找不到匹配的servlet的时候,才会走DefaultServlet
  3. 我们可以在项目中的web.xml中对tomcat/config/web.xml中的配置进行覆盖,即项目中的web.xml相对于tomcat中的web.xml有更高的优先级。

3、如何让springmvc处理所有请求?

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

4、问题来了:静态资源404了

当我们将上面springmvc的url-pattern改为/时,大家可以自己去试试,此时再访问静态资源的时候,如下图,会报404,这个请求被DispatcherServlet 接收了,但是这个servlet默认情况下并没有处理静态资源的能力,即找不到请求的资源,所以才会报404

springmvc提供了2种解决方案,来看下。

5、方案2:使用mvc:default-servlet-handler/

在springmvc的配置文件中添加下面配置

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

这里说一下原理

1、加入mvc:default-servlet-handler/配置后,框架会创建DefaultServletHttpRequestHandler对象,这个对象会将请转发给tomcat的default这个servlet处理,所以静态资源就可以正常访问了

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

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

6、方案2:使用mvc:resources/

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

需要在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行<mvc:annotation-driven/>也必须加上,如果不加上,@RequestMapping的请求就无法处理了
  • 这种用法不依赖于web容器,所以比第一种方案要好一些,也建议大家用这种方案。

上面代码中配置了3行mvc:resources,可以优化下,如下

    <mvc:annotation-driven/>
    <mvc:resources mapping="/static/**" location="/static/"/>

7、总结

  • tomcat默认能够处理jsp和静态资源,是因为tomcat中默认有2个servlet:default和jsp
  • 到此我们已经知道如何让springmvc来处理所有请求了,只需要在web.xml中调整一下url-pattern的值为/就可以了
  • 默认情况下,springmvc无法处理静态资源,本文介绍了2种方式,大家可以回头在再去看看,第一种需要依赖于web容器中的default这个servlet,使用上面对web容器有依赖作用;而第2种方式是springmvc推荐的方式,更好一些,对web容器没有依赖
  • 不管用那种方式,都不要忘记了<mvc:annotation-driven/>这个注解,否则咱们自定义的controller中的@RequestMapping就无效了
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值