###项目中需要将图片放在磁盘上,不能将图片放在webapp下面!
springboot默认配置基本上可以满足我们的日常需要
但是项目中大量用户上传的图片,不能放在tomcat下面,这样子每次重新部署项目的时候,图片就失效了,很是麻烦。
所以此时就需要自定义配置springboot的项目静态文件映射
springboot默认的配置规则
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache()
.getCachecontrol().toHttpCacheControl();
//1 通过 webjars
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
//通过指定文件夹
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
// 映射路径
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(
//静态文件夹
this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
}
通过查看springboot web配置 静态资源源代码,静态配置资源存在两种配置方法:
配置方法1 :
springboot 所有的 /webjars/** 到 classpath:/META-INF/resources/webjars/ 路径下找资源
可以根据 webjars jar包依赖导入相应的静态资源:
我们导入jq依赖:
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
访问:
http://localhost:8181/webjars/jquery/3.4.1/jquery.js
配置方法2 :
/**
* Path pattern used for static resources.
*/
private String staticPathPattern = "/**";
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
/**
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/].
*/
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
public String[] getStaticLocations() {
return this.staticLocations;
}
映射 /** 到 静态资源文件夹
classpath:/static
classpath:/public
classpath:/resources
classpath:/META-INF/resources
/ : 当前项目路径
到本地文件路径也就是 resource/static/ 下面
访问时可以:
localhost:8080/+资源路径+资源名
例如我的项目结构!
此时我访问的静态资源为:
localhost:8080/js/jquery.min.js
如果配置 jquery.min.js 直接在static下面 访问则是
localhost:8080/jquery.min.js
我们可以进行配置:
存在静态资源属性
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
public String[] getStaticLocations() {
return this.staticLocations;
}
public void setStaticLocations(String[] staticLocations) {
this.staticLocations = appendSlashIfNecessary(staticLocations);
}
.... 省略 ....
}
映射路径
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
//映射路径
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(
this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
staticPathPattern 映射路径由 String staticPathPattern = this.mvcProperties.getStaticPathPattern(); 提供
getStaticPathPattern();
private String staticPathPattern = “/**”; 此代码位于
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
.....
private String staticPathPattern = "/**";
....
}
所以配置映射 可以在配置文件里面配置:
spring.mvc.static-path-pattern=/**
但现在需要自定义映射规则:
有两种方法一种是基于配置文件,另一种是基于代码层面配置。
1 基于配置文件
#配置内部访问地址和外部图片访问地址 /myimgs/**
spring.mvc.static-path-pattern=/**
spring.resources.static-locations=file:C:/Users/tizzy/Desktop/img/,classpath:/static/
映射 /** 到 本地磁盘路径下存放的图片,和tomcat中的图片路径
访问路径则是
localhost:8080/jquery.min.js
localhost:8080/ 图片名
2 基于代码层面配置
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//addResourceHandler是指你想在url请求的路径
//addResourceLocations是图片存放的真实路径
registry.addResourceHandler("/**").addResourceLocations("file:C:/Users/tizzy/Desktop/img/").addResourceLocations("classpath:/static/");
super.addResourceHandlers(registry);
}
}
3 设置首页
static String[] getResourceLocations(String[] staticLocations) {
String[] locations = new String[staticLocations.length
+ SERVLET_LOCATIONS.length];
System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length);
System.arraycopy(SERVLET_LOCATIONS, 0, locations, staticLocations.length,
SERVLET_LOCATIONS.length);
return locations;
}
private Optional<Resource> getWelcomePage() {
String[] locations = getResourceLocations(
// 映射路径 /** 到静态资源文件夹
this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml)
.filter(this::isReadable).findFirst();
}
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
所以只需要 将 index.html 放置在任意映射的静态资源文件夹目录下即可。
4 设置图标
@Configuration
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
public static class FaviconConfiguration implements ResourceLoaderAware {
private final ResourceProperties resourceProperties;
private ResourceLoader resourceLoader;
public FaviconConfiguration(ResourceProperties resourceProperties) {
this.resourceProperties = resourceProperties;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
//设置资源路径
faviconRequestHandler()));
return mapping;
}
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
//设置资源路径
requestHandler.setLocations(resolveFaviconLocations());
return requestHandler;
}
//资源路径
private List<Resource> resolveFaviconLocations() {
String[] staticLocations = getResourceLocations(
//默认的静态资源路径
this.resourceProperties.getStaticLocations());
List<Resource> locations = new ArrayList<>(staticLocations.length + 1);
Arrays.stream(staticLocations).map(this.resourceLoader::getResource)
.forEach(locations::add);
locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations);
}
}
将图标放置到静态资源文件夹下面即可。