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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐