一、配置最终效果
这一节主要是展示最终配置出来的效果,并且讲解下为什么需要这么配置的原因。
通过虚拟路径映射的配置以后,可直接让页面重定向到指定URL完成外部静态资源调用,例如访问:localhost:8080/download/image/d9baf55f-b377-4094-9d37-428bdf1d4638.jpg,效果如下:
注意:文件在Windows系统的绝对路径是:E:\test\image\图片.jpg。
为什么需要配置并调用后台外部的静态资源,而不是把图片放在项目内部?因为自己写入项目中,静态文件和部署项目包是耦合的,不易于管理。
二、静态资源配置
HTML、CSS、图片和文档都属于静态资源,目前来说有2种比较方便的静态资源配置方式:实现WebMvcConfigurer类或者配置application.properties
2.1 方式一:实现WebMvcConfigurer类
注意:在SpringBoot2.0及Spring 5.0 WebMvcConfigurerAdapter已被废弃,就是网上写的很多继承WebMvcConfigurerAdapter类的实现方案,现如今官方推荐实现WebMvcConfigurer类。
代码如下:
application.properties中:
#用于网页请求外部静态资源(图片、PDF等)
web.upload-base-path=E://test/
web.upload-image-path=${web.upload-base-path}image/
#用于网页请求项目内部的js、css文件
spring.resources.static-locations=classpath:/static/
配置类:
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Value("${web.upload-image-path}")
String IMAGE_PATH;
/**
* 定义静态资源虚拟访问路径
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//定义虚拟路径,所有download路径打头的资源都直接在硬盘里面查找。
//虚拟路径/download/image/**你可以换成其他的,如:/image/**。
//路径字段IMAGE_PATH你可以写成绝对路径,我这样弄是为了解耦。
registry.addResourceHandler("/download/image/**").addResourceLocations("file:" + IMAGE_PATH);
}
}
推荐这种配置方式,这样定义虚拟路径后,仅仅是download开头的URL会映射到该配置,而内部静态js、css文件则不会受到干扰,依然会访问classpath:/static/路径。
最后补充一点, 为什么我不采用继承新的WebMvcConfigurationSupport来配置?原因如下:一旦继承WebMvcConfigurationSupport后就会出现新的问题,会发现SpringBoot的WebMvc自动配置失效,具体表现比如访问不到静态资源(js,css等)了,继承配置类后,相当于容器中已经有了WebMvcConfigurationSupport,所以默认配置都不会生效,都得自己在配置文件中配置。换句话来说,通过继承的方式,我们的applicaiton.properties的配置会无效化。
2.2 方式二:配置application.properties
个人不推荐这种方式,在个人实现过程中,该种配置方法会导致项目内部静态js、css文件出现404无法请求,因为这些文件也属于静态文件,所以在外部资源位置无法找到。
该种方式通过定义spring.mvc.static-path-pattern和spring.resources.static-locations来进行资源访问的映射配置,这俩货往往是成对儿出现的,static-path-pattern用于捕获URL,static-locations用于资源的路径配置。另外,其均具有默认值。
//默认值为/**
//优先匹配download/image/**,然后匹配/**
spring.mvc.static-path-pattern= download/image/**, /**
//默认值为 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
spring.resources.static-locations=classpath:/static/,file:${web.upload-image-path}
这种方式简单到是简单,关键是内含映射关系太复杂了,而且容易出现无法访问项目内部静态文件的问题。
三、例子讲解
希望能用最简单的例子进行展示
外部图片路径:E:\test\image\图片名.jpg
项目结构目录:
application.preperties配置:
#file upload
web.upload-base-path=E://test/
web.upload-image-path=${web.upload-base-path}image/
虚拟路径配置:
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Value("${web.upload-image-path}")
String IMAGE_PATH;
/**
* 定义静态资源虚拟访问路径
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//定义虚拟路径,所有download路径打头的资源都直接在硬盘里面查找。
registry.addResourceHandler("/download/image/**").addResourceLocations("file:" + IMAGE_PATH);
}
}
Controller层:
@Controller
public class TestController {
/**
* 用户访问localhost:8080/testImageDownLoad接口就会被重定向到imageUrl
* @return String 图片位置
*/
@GetMapping("/testImageDownLoad")
public String testImageDownLoad() {
String imageUrl = "redirect:http://localhost:8080/download/image/8008b450-872a-40a2-b5bf-07cbba949c90.jpg";
return imageUrl ;
}
}