Spring Boot静态资源映射(以图片上传并显示为例)
Web程序的开发离不开上传功能,而Spring Boot推荐将web开发为jar项目,与传统的war项目不同,jar项目将程序的全部文件打包成一体,类似于一个压缩包,静态资源也全都包含其中,这就引发了文件上传不到包内,更无法加载调用的问题。
解决这一问题,我们应当让项目直接引用jar包外部的静态资源,即更改静态资源映射路径,而且在调整静态资源时,只需修改并上传相应的文件,不用重新打包整个项目上传服务器,大大提高了程序的维护效率。
1)Spring Boot默认资源加载路径
Spring Boot有默认的资源加载路径,即classpath,源码如下:
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/" };
也就是说默认的资源加载路径有:
/META-INF/resources/
/resources/
/static/
/public/
参考文章:spring boot 加载资源路径配置和classpath问题
Spring Boot会根据目录结构自动匹配路径,优先级顺序为:META-INF/resources > resources > static > public 。
目录示例:
若目录结构如上图所示,在/resources/static/img/下有一图片名为ajax.jpg,我们在引用时写/img/ajax.jpg即可,也就是匹配了static路径。
2)Spring Boot静态资源映射路径修改
有关Spring Boot静态资源处理的各种问题可以参考下面这篇文章,我认为非常具有学习价值。
参考文章:Spring Boot 静态资源处理
下面我就说一下静态资源映射路径修改的两种方法,也就是更改第一部分所说的默认资源加载路径:
2.1 新建WebMvcConfigurer类
2.1.1 修改包内路径
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebAppConfigurer implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/META-INF/resources/")
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/public/");
super.addResourceHandlers(registry);
}
}
若addResourceHandler()内为/** ,则会覆盖系统默认路径,需重新在addResourceLocations()内添加路径才会起作用;
若addResourceHandler()内为/xxxx/**,则引用静态资源时加不加/xxxx/ 均可,因为系统默认配置也会起作用;
addResourceLocations()中优先级先添加的高于后添加的。
参考文章:Springboot 静态资源路径配置的两种方法
2.1.2 引用包外资源
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebAppConfigurer implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//WINDOWS用
registry.addResourceHandler("/img/**").addResourceLocations("file:D:/web/img/");
//LINUX用
registry.addResourceHandler("/img/**").addResourceLocations("file:/usr/local/img/");
}
}
代码可根据系统选用,在Windows中,引用图片时写"/img/ajax.jpg"即引用"D:/web/img/“下文件;
在Linux中,引用图片时写”/img/ajax.jpg"即引用"/usr/local/img/"下文件。
参考文章:SpringBoot 配置本地资源映射路径已解决
2.2 修改配置文件
Spring Boot还可以通过直接修改 application.properties(或.yml)的方式实现映射。
# 默认值
spring.mvc.static-path-pattern=/**
# 默认值
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
目录示例:
spring.mvc.static-path-pattern:静态资源的加载起点(个人看法)。
与新建类方法相同,若写为/** ,则会覆盖系统默认路径,需在spring.resources.static-locations内重新添加路径才会起作用;
若修改为 /newPath/** ,则加载/resources/static/img/ajax.jpg,需要写为/newPath/img/ajax.jpg,修改前为/img/ajax.jpg。
spring.resources.static-locations:静态资源的默认加载路径。
添加新路径示例:
web.upload-path=d:/myfile/upload
web.front-path=d:/myfile/front
spring.resources.static-locations=file:${web.upload-path},file:${web.front-path}
参考文章:springBoot 连接打包成jar包运行时,获取图片上传文件、前端页面等文件
3)Spring Boot文件上传
HTML页面与war项目上传文件没有区别,就不在此给出,有需要可以在网上查询。
3.1 引用组件(pom.xml)
<dependencies>
<!-- Apache Commons FileUpload组件依赖, 由于不属于Spirng Boot,所以需要加上版本 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
</dependencies>
参考书籍:《Spring Boot 2 企业应用实战》(电子工业出版社 疯狂软件编著)
3.2 通过controller转存
依托Spring Boot开发的web项目,需要将上传的静态资源引入静态资源映射的路径中,才能实现显示。
直接上代码(转存部分):
if(!file.isEmpty()){
// Windows
//String imgPath = "D:/web/img/";
// Linux
String imgPath = "/usr/local/img/";
// 上传的文件名
String imgName = file.getOriginalFilename();
File filepath = new File(imgPath,imgName);
// 判断路径是否存在,如果不存在就创建一个
if (!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
// 将上传的文件保存到一个目标文件当中
file.transferTo(filepath);
}else {
System.out.println("图片上传失败!");
}
上传路径也可以在application.properties(或.yml)中定义,并在controller中引用。
配置文件:
web.upload-path=D:/web/img/
web.upload-path属于自定义属性,用于指定一个路径,注意要以/结尾;
参考文章:springboot静态资源路径配置与部署项目文件上传路径问题
controller:
@Value("${web.upload-path}")
private String uploadPath;