在SpringBoot中有默认的静态资源文件相关配置,需要通过如下源码跟踪:
WebMvcAutoConfiguration-->configureResourceChain(method)-->ResourceProperties中配置了默认的静态资源路径:

其默认的优先级:META/resources > resources > static > public 
下面通过案例实践验证静态资源的应用

章节要点:
1、传统静态资源引入;
2、WebJar使用;
3、版本管理;
4、静态资源配置抽取;
5、WAR包常规容易部署;


1、传统静态资源文件的引入:
1.1、在默认的路径下添加jquery.js:

1.2、修改原jsp目录下的home.jsp页面:
<%@ page contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>JSP</title>
<script type="text/javascript" src="/js/jquery/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var myDate = new Date();
$("#dateInput").val(myDate.toLocaleString());
});
function increase(){
var currentPage=$("#currentPage");
currentPage.val(Number(currentPage.val())+1);
alert($("#currentPage").val());
}
</script>
</head>
<body>
<h1>Hello ${name} from JSP!</h1>
<div>
<label id="showLab">进入页面时间</label>
<input type="text" id="dateInput" style="width: 200px"/>
<input type="text" id="currentPage" style="width: 200px" value=1>
<a href="#" onclick="increase()">增一</a>
</div>
</body>
</html>

1.3、此时我们直接访问请求页面:

点击增一,执行js

系统默认配置验证完成,能够正常加载使用。

1.4、下面我们开始验证自定义静态资源文件目录实现,尝试两种不同的方案(1、仍然在classpath目录下,新建非static目录;2、在WEB-INF目录下新建static/js目录),根据之前的实践,我们仅需在实现WebMvcConfigurerAdapter接口的配置类中添加addResourceHandlers方法即可(优先级为先添加的高于后添加的)。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/mystatic/**").addResourceLocations("classpath:/mystatic/");
registry.addResourceHandler("/static/js/**").addResourceLocations("/WEB-INF/static/js/");
}

1.5、添加对应的静态文件目录以及文件:


如上目前在3个不同的路径下均有对应的js文件。

1.6、在页面中添加js的加载:

1.7、我们发出请求查看,通过F12查看开发者模式下请求状态:



3种不同的配置均能够生效,均能够找到目前文件。
综上:
1、可以发现通过重写addResourceHandlers的方式添加静态资源请求映射不会覆盖系统原有默认映射,能够叠加使用;
2、通过配置对应的请求规则,映射值不同的资源文件目录。但采用默认的资源路径时,请求地址无需加入static,如上/js/jquery/jquery-1.11.3.min.js系统自动至默认的路径(目前为classpath:/static/)下查找,如果/static/js/jquery/jquery-1.11.3.min.js则默认情况下会在classpath:/static/路径下继续查找static目录,显然是没有的(当然本案例中已经将/static/js/**请求重新映射资源路径)。
3、如果需要将系统默认的/**默认资源路径更改,需要添加registry.addResourceHandler("/**").addResourceLocations("/WEB-INF/static/");即可,通常无需此设置。

2、在springboot中静态资源文件的引用,可以通过webjars加载,WebJars将我们常用的js打包成了jar包。WebJars:http://www.webjars.org/
2.1、首先在POM文件中添加相关依赖:
<!-- webjar依赖 -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>1.11.3</version>
</dependency>
2.2、在页面中添加js文件的加载:

2.3、请求页面查看请求效果:


能够如愿正常加载访问。
2.4、既然通过POM文件可以直接指定加载的目标js库的版本,那么如果我们修改版本,是不是可以不需要手动修改引入js的版本路径呢:
2.4.1、继续添加相关依赖:
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
</dependency>
2.4.2、新建一个控制器,如下:
@Controller
public class WebJarController {
private final WebJarAssetLocator assetLocator = new WebJarAssetLocator();

@ResponseBody
@RequestMapping("/webjarslocator/{webjar}/**")
public ResponseEntity locateWebjarAsset(@PathVariable String webjar, HttpServletRequest request) {
try {
String mvcPrefix = "/webjarslocator/" + webjar + "/";
String mvcPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String fullPath = assetLocator.getFullPath(webjar, mvcPath.substring(mvcPrefix.length()));
return new ResponseEntity(new ClassPathResource(fullPath), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
}
2.4.3、在页面中添加引入:
<script type="text/javascript" src="/webjarslocator/jquery/jquery.js"></script>
2.4.5、请求页面验证:




一切都很正常,仅仅在引入地址省去了版本路径。

3、版本管理
在项目中,当我们资源内容发生变化时,由于浏览器缓存,用户本地的静态资源还是旧的资源,为了防止这种情况导致的问题,我们可能会手动在请求url的时候加个版本号或者其他方式。
此时在springboot中,我们可以通过如下两种方式解决此问题。
3.1、资源名-md5 方式:
3.1.1、在application.properties文件中添加:
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
3.1.2、通过paths的设置,所有的请求将均被处理,转换为相应的版本话地址,那么我们在jsp页面中引入的url需要简单处理,首先添加
package com.shf.springboot.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.servlet.resource.ResourceUrlProvider;
/**
* 主要作用于版本话管理静态资源
* @author song
*/
@ControllerAdvice
public class ControllerConfig {
@Autowired
ResourceUrlProvider resourceUrlProvider;
@ModelAttribute("urls")
public ResourceUrlProvider urls() {
return this.resourceUrlProvider;
}
}
然后引入js:

将上述论证的引入js的多种模式均验证,验证结果如下:

可以发现,仅默认请求的/**查找classpath:static以及webjars两种默认资源映射能够实现MD5版本化,自定义的/static/js/**方式能够正常加载,而采用通过webjarslocator资源定位的则无法获取资源文件。
3.2:采用版本号方式
3.2.1、在application.properties文件中配置:
#spring.resources.chain.strategy.content.enabled=true
#spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/**
spring.resources.chain.strategy.fixed.version=v1.0.0
3.2.2、再次请求验证查看验证结果:

可以发现,效果与md5方式差不多,仅默认请求的/**查找classpath:static以及webjars两种默认资源映射能够实现版本化。
综上:当请求的地址为md5方式时,会尝试url中的文件名中是否包含-,如果包含会去掉后面这部分,然后去映射的目录(如/static/)查找/js/common.js文件,如果能找到就返回。
当请求的地址为版本号方式时,会在url中判断是否存在/v1.0.0 ,如果存在,则先从URL中把 /v1.0.0 去掉,然后再去映射目录查找对应文件,找到就返回。


4、3中描述的版本话管理,其实在项目实际使用中,对于引入的第三方js相对还比较稳定,不会常有变化。版本化管理不一定是硬性需求,同时我们js引入通常抽取为公共的jsp页面,无需每个页面添加,修改也比较容易:
4.1、新建一个head.jsp页面:

<%@ page contentType="text/html;charset=UTF-8" %>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script type="text/javascript" src="/mystatic/js/jquery/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="/static/js/jquery/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="/js/jquery/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="/webjars/jquery/1.11.3/jquery.js"></script>
<script type="text/javascript" src="/webjarslocator/jquery/jquery.js"></script>
<script type="text/javascript" src="${urls.getForLookupPath('/js/jquery/jquery-1.11.3.min.js')}"></script>
<script type="text/javascript" src="${urls.getForLookupPath('/static/js/jquery/jquery-1.11.3.min.js')}"></script>
<script type="text/javascript" src="${urls.getForLookupPath('/webjarslocator/jquery/jquery.js')}"></script>

4.2、在home.jsp中include:

4.3、请求验证,与上述效果一致:


5、打成war部署自定义容易验证(jar模式启动无需验证,jar模式下无法读取WEB-INF目录):

此时部署非根路径部署,需要调整为如下:
5.1、抽取一个公共jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
5.2、在home.jsp中添加include:
<%@include file="/WEB-INF/jsp/include/taglib.jsp" %>
5.3、在head.jsp中修改原引入:
<%@ page contentType="text/html;charset=UTF-8" %>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script type="text/javascript" src="${ctx }/mystatic/js/jquery/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="${ctx }/static/js/jquery/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="${ctx }/js/jquery/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="${ctx }/webjars/jquery/1.11.3/jquery.js"></script>
<script type="text/javascript" src="${ctx }/webjarslocator/jquery/jquery.js"></script>
<script type="text/javascript" src="${ctx }${urls.getForLookupPath('/js/jquery/jquery-1.11.3.min.js')}"></script>
<script type="text/javascript" src="${ctx }${urls.getForLookupPath('/static/js/jquery/jquery-1.11.3.min.js')}"></script>
<script type="text/javascript" src="${ctx }${urls.getForLookupPath('/webjarslocator/jquery/jquery.js')}"></script>
<script type="text/javascript" src="${ctx }${urls.getForLookupPath('/webjars/jquery/1.11.3/jquery.js')}"></script>
5.4、此时我们现在开发环境启动验证:

5.5、部署war包验证:

此时可以发现两种环境下,JS的引入与之前的效果一致,仅webjarslocator无法正常加载。

总结
有这么多方式来管理我们的资源文件,然而在实际应用中虽然也都有可能用到(存在就有存在的道理嘛): 
1. 我们使用第三方的库时,建议使用webjars的方式,通过动态版本号(webjars-locator 的方式)来使用(因为第三方库在项目开发中变动频率很小,即便是变动也是版本号的修改)。 
2. 我们使用自己存放在静态资源映射目录中的资源的时候,建议使用md5 资源文件名的方式来使用(项目开发中一些css、js文件会经常修改)。 
3. 项目素材文件建议放到 classpath:/static (或其他)目录中,打包在项目中,通过CMS维护的一些图片和资源,我们使用配置引用到具体的磁盘绝对路径来使用。 
4. 注意使用md5文件名方式的时候,Spring 是有缓存机制的,也就是说,在服务不重启的情况下,你去变动修改这些资源文件,其文件名的md5值并不会改变,只有重启服务再次访问才会生效。如果需要每次都获取实际文件的md5值,需要重写相关类来实现,我们不建议这样做,因为一直去计算文件md5值是需要性能代价的。


springboot下静态资源的处理(转)的更多相关文章

  1. SpringBoot - 搭建静态资源存储服务器

    目录 前言 环境 实现效果 具体实现 文件上传 配置类 上传接口 上传实现 辅助类 实体 上传测试 文件访问 配置类 项目源码 前言 记录下SpringBoot下静态资源存储服务器的搭建. 环境 wi ...

  2. SpringBoot 配置静态资源映射

    SpringBoot 配置静态资源映射 (嵌入式servlet容器)先决知识 request.getSession().getServletContext().getRealPath("/& ...

  3. IntelliJ IDEA+SpringBoot中静态资源访问路径陷阱:静态资源访问404

    IntelliJ IDEA+SpringBoot中静态资源访问路径陷阱:静态资源访问404 .embody{ padding:10px 10px 10px; margin:0 -20px; borde ...

  4. springboot配置静态资源访问路径

    其实在springboot中静态资源的映射文件是在resources目录下的static文件夹,springboot推荐我们将静态资源放在static文件夹下,因为默认配置就是classpath:/s ...

  5. 【SpringBoot】06.SpringBoot访问静态资源

    SpringBoot访问静态资源 1.SpringBoot从classpath/static的目录 目录名称必须是static 启动项目,访问http://localhost:8080/0101.jp ...

  6. springboot设置静态资源不拦截的方法

    springboot设置静态资源不拦截的方法 springboot不拦截静态资源需配置如下的类: import org.springframework.context.annotation.Confi ...

  7. springboot访问静态资源404

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...

  8. spring-boot配置静态资源映射的坑:properties文件不能添加注释

    如此博文所述,Spring Boot 对静态资源映射提供了默认配置 默认将 /** 所有访问映射到以下目录:classpath:/staticclasspath:/publicclasspath:/r ...

  9. SpringBoot之静态资源放行

    为了提高开发效率,编写对应的代码生成器.代码生成器主要有两个方面,一个是在线Web,另外一个是运行某个类. 使用的技术是SpringBoot+MyBatis-Plus+MySQL+JDK8. 在编写在 ...

随机推荐

  1. SpringBoot与Dubbo整合-项目搭建

    本章节建立生产者和消费者来演示dubbo的demo 生产者:springboot-dubbo-provider 和 消费者:springboot-dubbo-consumer 工程配置详解 Apach ...

  2. ElasticSearch vs 关系型数据库

    它们之间的关系,如下图所示.

  3. sql server 怎样用select语句调用自定义表值函数

    --自定义函数的参数是表的字段,这种情况要用cross apply啦Select B.* FROM [master].[dbo].[分列测试] A cross apply dbo.f_split(应用 ...

  4. python的循环测试

    这段代码要实现的是:猜数字58 ,猜三次,三个判断条件和一个结束条件.判断为等于58的时候跳出循环. 首先定义一个固定变量 int 函数是更改input输入的文字类型 if guess_age == ...

  5. newgrp---将当前登录用户临时加入到已有的组中

    Linux中的newgrp命令主要是将当前登录用户临时加入到已有的组中,用法如下: [linuxidc@localhost etc]$ newgrp grptest 上面命令的含义是将用户linuxi ...

  6. ST和LCA和无根树连接

    #include <stdio.h> #include <iostream> #include <string.h> #include <algorithm& ...

  7. springboot整合Beetl、BeetlSql实现ajax分页

    Beetl是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,超过当前流行的模板引擎.而且还易学易用. BeetSql是一个 ...

  8. Rsync 指令的使用方法

    RsyncLinux版下载:http://rsync.samba.org/download.htmlWindows版下载:https://www.itefix.no/i2/cwrsync-get 选( ...

  9. 有關AWS EC2 (EBS 收費)的問題

    有關AWS EC2 (EBS 收費)的問題 之前一陣子的時候,公司在使用Amazone Web Service (AWS)的 EC2 (Amazon Elastic Compute Cloud).不過 ...

  10. HDU 多校联合 6045

    Is Derek lying? Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...