1.解决Spring Boot访问resources目录下的static资源问题
下面从读、写两个方面解析访问和上传static目录下的内容
1.2 读取
读取资源(也就是web端访问static资源)其实就很简单,Spring Boot 默认就配置了 /static/** 映射,所以无需任何配置就能访问。但是需要注意的是,如果使用了模板引擎(比如 thymeleaf),就需要手动配置,以下演示两种通过模板引擎访问static资源的方式:
-
直接将资源在templates目录下,然后就能按路径访问,因为默认就会在templates目录下找静态资源
访问hello.html可以直接:localhost:8080/hello.html -
如果要直接访问resource/static,那就需要在application.yml中添加如下配置,否则就会出现404
spring: mvc: static-path-pattern: /static/**
2. 写入
也称上传资源,其实是不建议往resources目录下直接写入业务相关的文件(尤其是存储图片)的,因为后续可能会遇到
- 资源的实时访问问题,比如上传图片后,然后再访问,可能需要重启才能继续访问
- jar对resources目录进行保护措施,可能读取不到上传的资源
但是有些极少量的文件需要存储到resources目录下,这就需要先获取到reources下的相应目录,此时应该考虑将来运行jar包时不能出错,因此我推荐一下两种方式获取static目录:
-
通过ResourceUtils工具获取static目录
try { File staticDir = new File (ResourceUtils.getURL("classpath:static").getPath()); } catch (FileNotFoundException e) { // static 目录不存在! e.printStackTrace(); }
-
通过 ClassPathResource 获取
// 这里要具体到你要访问的文件,然后拿到文件流对象,你就可以放肆操作了! ClassPathResource classPathResource = new ClassPathResource("/static/xxx/xxx.png"); InputStream inputStream = classPathResource.getInputStream(); // 转成字节数组 final byte[] bytes = IOUtil.toByteArray(inputStream); // 比如把图片装成 base64 编码的字符串 String imgStr = "data:image/png;base64, " + Base64.getEncoder().encodeToString(bytes);
1.3 小结
最后还想说一下,如果要上传图片,最好不要直接在jar包里上传图片,应该考虑:
-
建立专门的静态资源服务器(图片服务器)可以使用nginx
-
其次可以考虑做成本地硬盘上的映射目录:
添加配置文件WebMVCConfig,然后在添加资源映射:
@Slf4j @Configuration public class WebMVCConfig implements WebMvcConfigurer { @Value("${logo-img.request-path}") private String logoReqPath; // 请求地址 @Value("${logo-img.local-path}") private String logoLocPath; // 本地存放资源目录的绝对路径 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { File logoDir = new File(logoLocPath); boolean flag = false; if (!logoDir.exists()) flag = logoDir.mkdirs(); if (flag) log.info("已成功创建资源 logo 目录:{}", logoLocPath); log.info("getAbsolutePath = {}", logoDir.getAbsolutePath()); log.info("getPath = {}", logoDir.getPath()); registry.addResourceHandler(logoReqPath) .addResourceLocations("file:" + logoDir.getAbsolutePath() + File.separator); } }
上述参数在application.yml配置如下:
最后访问
/logo-view-s/xxx.png
就会映射到D:/test/logos/xxx.png