Spring Boot2 系列教程(十一)Spring Boot 中的静态资源配置
当我们使用 SpringMVC 框架时,静态资源会被拦截,需要添加额外配置,之前老有小伙伴在微信上问松哥 Spring Boot 中的静态资源加载问题:“松哥,我的 HTML 页面好像没有样式?”,今天我就通过一篇文章,来和大伙仔细聊一聊这个问题。
1. SSM 中的配置
要讲 Spring Boot 中的问题,我们得先回到 SSM 环境搭建中,一般来说,我们可以通过 <mvc:resources />
节点来配置不拦截静态资源,如下:
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/html/**" location="/html/"/>
由于这是一种Ant风格的路径匹配符,/**
表示可以匹配任意层级的路径,因此上面的代码也可以像下面这样简写:
<mvc:resources mapping="/**" location="/"/>
这种配置是在 XML 中的配置,大家知道,SpringMVC 的配置除了在XML中配置,也可以在 Java 代码中配置,如果在 Java 代码中配置的话,我们只需要自定义一个类,继承自 WebMvcConfigurationSupport 即可:
@Configuration
@ComponentScan(basePackages = "org.javaboy.javassm")
public class SpringMVCConfig extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("/");
}
}
重写 WebMvcConfigurationSupport 类中的 addResourceHandlers 方法,在该方法中配置静态资源位置即可,这里的含义和上面 xml 配置的含义一致,因此无需多说。
这是我们传统的解决方案,在 Spring Boot 中,其实配置方式和这个一脉相承,只是有一些自动化的配置了。
2. Spring Boot 中的配置
在 Spring Boot 中,如果我们是从 https://start.spring.io
这个网站上创建的项目,或者使用 IntelliJ IDEA 中的 Spring Boot 初始化工具创建的项目,默认都会存在 resources/static
目录,很多小伙伴也知道静态资源只要放到这个目录下,就可以直接访问,除了这里还有没有其他可以放静态资源的位置呢?为什么放在这里就能直接访问了呢?这就是本文要讨论的问题了。
2.1 整体规划
首先,在 Spring Boot 中,默认情况下,一共有 5 个位置可以放静态资源,五个路径分别是如下 5 个:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/
前四个目录好理解,分别对应了 resources 目录下不同的目录,第 5 个 /
是啥意思呢?我们知道,在 Spring Boot 项目中,默认是没有 webapp
这个目录的,当然我们也可以自己添加(例如在需要使用JSP的时候),这里第 5 个 /
其实就是表示 webapp 目录中的静态资源也不被拦截。如果同一个文件分别出现在五个目录下,那么优先级也是按照上面列出的顺序。
不过,虽然有 5 个存储目录,除了第 5 个用的比较少之外,其他四个,系统默认创建了 classpath:/static/
, 正常情况下,我们只需要将我们的静态资源放到这个目录下即可,也不需要额外去创建其他静态资源目录,例如我在 classpath:/static/
目录下放了一张名为 1.png 的图片,那么我的访问路径是:
http://localhost:8080/1.png
这里大家注意,请求地址中并不需要 static,如果加上了 static 反而多此一举会报 404 错误。很多人会觉得奇怪,为什么不需要添加 static 呢?资源明明放在 static 目录下。其实这个效果很好实现,例如在 SSM 配置中,我们的静态资源拦截配置如果是下面这样:
<mvc:resources mapping="/**" location="/static/"/>
如果我们是这样配置的话,请求地址如果是 http://localhost:8080/1.png
实际上系统会去 /static/1.png
目录下查找相关的文件。
所以我们理所当然的猜测,在 Spring Boot 中可能也是类似的配置。
2.2 源码解读
胡适之先生说:“大胆猜想,小心求证”,我们这里就通过源码解读来看看 Spring Boot 中的静态资源到底是怎么配置的。
首先我们在 WebMvcAutoConfiguration 类中看到了 SpringMVC 自动化配置的相关的内容,找到了静态资源拦截的配置,如下:
可以看到这里静态资源的定义和我们前面提到的 Java 配置 SSM 中的配置非常相似,其中,this.mvcProperties.getStaticPathPattern() 方法对应的值是 /**
,this.resourceProperties.getStaticLocations() 方法返回了四个位置,分别是:
- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- classpath:/public/
然后在 getResourceLocations 方法中,又添加了 /
,因此这里返回值一共有 5 个。其中, /
表示 webapp
目录,即 webapp
中的静态文件也可以直接访问。静态资源的匹配路径按照定义路径优先级依次降低。因此这里的配置和我们前面提到的如出一辙。这样大伙就知道了为什么 Spring Boot
中支持 5 个静态资源位置,同时也明白了为什么静态资源请求路径中不需要 /static
,因为在路径映射中已经自动的添加上了 /static
了。
2.3 自定义配置
当然,这个是系统默认配置,如果我们并不想将资源放在系统默认的这五个位置上,也可以自定义静态资源位置和映射,自定义的方式也有两种,可以通过 application.properties 来定义,也可以在 Java 代码中来定义,下面分别来看。
2.3.1 application.properties
在配置文件中定义的方式比较简单,如下:
spring.resources.static-locations=classpath:/
spring.mvc.static-path-pattern=/**
第一行配置表示定义资源位置,第二行配置表示定义请求 URL 规则。以上文的配置为例,如果我们这样定义了,表示可以将静态资源放在 resources 目录下的任意地方,我们访问的时候当然也需要写完整的路径,例如在 resources/static
目录下有一张名为 1.png 的图片,那么访问路径就是 http://localhost:8080/static/1.png
,注意此时的 static
不能省略。
2.3.2 Java 代码定义
当然,在 Spring Boot 中我们也可以通过 Java 代码来自定义,方式和 Java 配置的 SSM 比较类似,如下:
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/aaa/");
}
}
这里代码基本和前面一致,比较简单,不再赘述。
3. 总结
这里需要提醒大家的是,松哥见到有很多人用了 Thymeleaf 之后,会将静态资源也放在 resources/templates 目录下,注意,templates 目录并不是静态资源目录,它是一个放页面模板的位置(你看到的 Thymeleaf 模板虽然后缀为 .html,其实并不是静态资源)。好了,通过上面的讲解,相信大家对 Spring Boot 中静态资源的位置有一个深刻了解了,应该不会再在项目中出错了吧!
关注公众号【江南一点雨】,专注于 Spring Boot+微服务以及前后端分离等全栈技术,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货!
Spring Boot2 系列教程(十一)Spring Boot 中的静态资源配置的更多相关文章
- Spring Boot2 系列教程(八)Spring Boot 中配置 Https
https 现在已经越来越普及了,特别是做一些小程序或者公众号开发的时候,https 基本上都是刚需了. 不过一个 https 证书还是挺费钱的,个人开发者可以在各个云服务提供商那里申请一个免费的证书 ...
- Spring Boot2 系列教程(五)Spring Boot中的 yaml 配置
搞 Spring Boot 的小伙伴都知道,Spring Boot 中的配置文件有两种格式,properties 或者 yaml,一般情况下,两者可以随意使用,选择自己顺手的就行了,那么这两者完全一样 ...
- Spring Boot2 系列教程(十三)Spring Boot 中的全局异常处理
在 Spring Boot 项目中 ,异常统一处理,可以使用 Spring 中 @ControllerAdvice 来统一处理,也可以自己来定义异常处理方案.Spring Boot 中,对异常的处理有 ...
- Spring Boot2 系列教程(十)Spring Boot 整合 Freemarker
今天来聊聊 Spring Boot 整合 Freemarker. Freemarker 简介 这是一个相当老牌的开源的免费的模版引擎.通过 Freemarker 模版,我们可以将数据渲染成 HTML ...
- Spring Boot2 系列教程(九)Spring Boot 整合 Thymeleaf
虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在做前后端不分的开发,而在前后端不分的开发中,我们就会需要后端页面模板(实际上,即使前后端分离,也会在一些场景下需要使用页面模板, ...
- Spring Boot2 系列教程 (十一) | 整合数据缓存 Cache
如题,今天介绍 SpringBoot 的数据缓存.做过开发的都知道程序的瓶颈在于数据库,我们也知道内存的速度是大大快于硬盘的,当需要重复获取相同数据时,一次又一次的请求数据库或者远程服务,导致大量时间 ...
- Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源
多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问 ...
- Spring Boot2 系列教程(三十)Spring Boot 整合 Ehcache
用惯了 Redis ,很多人已经忘记了还有另一个缓存方案 Ehcache ,是的,在 Redis 一统江湖的时代,Ehcache 渐渐有点没落了,不过,我们还是有必要了解下 Ehcache ,在有的场 ...
- Spring Boot2 系列教程(三十一)Spring Boot 构建 RESTful 风格应用
RESTful ,到现在相信已经没人不知道这个东西了吧!关于 RESTful 的概念,我这里就不做过多介绍了,传统的 Struts 对 RESTful 支持不够友好 ,但是 SpringMVC 对于 ...
随机推荐
- Visual Studio 调试 —— 附加到进程(远程服务器)
一般在部署环境下不会有 Visual Studio 开发工具的,所以需要有 Remote Debugger(远程调试器) 才可以进行远程调试. Remote Debugger 获取 方法一:Visua ...
- Netty源码分析 (七)----- read过程 源码分析
在上一篇文章中,我们分析了processSelectedKey这个方法中的accept过程,本文将分析一下work线程中的read过程. private static void processSele ...
- Android开发必看知识
奇艺高清UI界面源代码 http://www.eoeandroid.com/thread-160824-1-1.html 搜索关键字飞入飞出效果 http://www.eoeandroid.com/t ...
- 大数据平台搭建 - cdh5.11.1 - hue安装及集成其他组件
一.简介 hue是一个开源的apache hadoop ui系统,由cloudear desktop演化而来,最后cloudera公司将其贡献给了apache基金会的hadoop社区,它基于pytho ...
- 03 jvm的组成
声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...
- PTA A1005&A1006
第三天 A1005 Spell It Right (20 分) 题目内容 Given a non-negative integer N, your task is to compute the sum ...
- ReactNative之Redux详解
用redux有一段时间了,感觉还是有必要把其相关的知识点系统的总结一下的,毕竟好记性不如烂笔头.上篇博客更新了关于<ES6中的迭代器.Generator函数以及Generator函数的异步操作& ...
- [PySpark] 01 - Preview parquet files in S3 ×××
本系列基于实际测试数据,质量保证,不自欺欺人. 实践是检验真理的唯一标准. Swipejobs is all about matching Jobs to Workers. Your challeng ...
- C++基础之泛型算法
标准库并未给每个容器添加大量功能,因此,通过大量泛型算法,来弥补.这些算法大多数独立于任何特定的容器,且是通用的,可用于不同类型的容器和不同的元素. 迭代器使得算法不依赖容器,但是算法依赖于元素的类型 ...
- 【Java】SpringBoot 中从application.yml中获取自定义常量
由于这里我想通过java连接linux,connection连接需要host.port.username.password及其他路径等等.不想每次修改的时候都去改源文件,所以想写在applicatio ...