Springboot静态资源访问、上传、回显和下载

简介: Springboot静态资源访问、上传、回显和下载

一、Springboot中默认静态资源存放的位置

springboot项目结构

        |———main |———java———代码
    |———src |    |
    |   |    |
    |   |    |———resources———静态资源配置
project |   |———test
    |———pom.xml
 

打包成jar包后得结构如下

    |———META-INF
    |     |——lib
project |     |
    |———BOOT-INF|
          |——classes——(项目结构java下面的class文件和resources下面的文件)

SpringBoot默认资源文件的存放位置如下四个

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = 
{ "classpath:/META-INF/resources/",
  "classpath:/resources/", 
  "classpath:/static/", 
  "classpath:/public/" 
};

classpath顾名思义,就是class的路径,打包前指的就是resources,打包后指的就是classes,

当我们想访问静态资源的时候会从上往下一个地址接一个地址的去找,找到即可返回

如:访问:localhost:8080/123.jpg时,访问顺序

src/main/resources/META-INF下/resoures/123.jpg

src/main/resources/resoures/123.jpg

src/main/resources/static/123.jpg

src/main/resources/public/123.jpg

直接通过浏览器访问上述路径下的文件时候有的是下载方式有的是直接预览,比如图片、txt、pdf、视频都是直接预览,而zip 、apk、docx、xlsx、ppt都是下载

二、手动配置资源存放的位置

1、把文件放在SpringBoot项目下的classpath中

方式1:配置类方式

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
 
/**
 * 主动设置URL匹配路径
 */
@Configuration
public class MyURLPatternConfiguration extends WebMvcConfigurationSupport {
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/fileData/**").addResourceLocations("classpath:/myFile/");
    super.addResourceHandlers(registry);
  }
}

此时:访问IP地址:端口号/fileData/时,就相当于到了src/main/resources/myFile文件夹中了,图示说明

注:此时默认的四个文件夹都失效了,如果想让默认的四个文件夹依然有效,那么可以在配置类中多次通 过.addResourceHandler添加指定那四个文件夹

方式2:配置文件方式

# 设置当URI为/fileData/**时,才进过静态资源
# 注:如果设置为/**,那么表示任何访问都会经过静态资源路径
spring.mvc.static-path-pattern=/fileData/**
 
# 自定义路径
# 注:自定义路径时,默认的四个文件夹下中的“META-INF下的resoures文件夹”仍然有效,其他三个文件夹失效
# (此时:访问ip:端口号/fileData/时,相当于访问到了 “自定义的文件夹”和 “META-INF下的resoures文件夹”);
# 注:搜索文件时,自定义的文件夹的优先级要高于默认的四个文件夹
 spring.resources.static-locations=classpath:/myFile/
 
# 提示:如果我们显式地把自定义文件夹  和 默认的四个文件夹都写出来,那么都会有效(此时,优先级 从左至右 依次降低)
#spring.resources.static-locations = classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/myFile/

2、把文件放在项目jar包之外的服务器磁盘中的某个文件夹中

方式1:通过配置类

/**
 * 添加一个静态资源路径的映射,不会覆盖默认的资源路径,以当前文件中的配置为例
 * 映射完成后在项目中请求http://localhost:8080/image/xx.png就可以读取到所映射的绝对路径中的xx.png了
 */
@Configuration
public class OaFileConfig implements WebMvcConfigurer {
 
    private String windir = "E:/oaFile";
    private String lindir = "/home/oa/oaFile/";
 
    /**
     * 实现资源映射访问路径方法
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        /**
         * 资源映射路径
         * addResourceHandler:访问映射路径
         * addResourceLocations:资源绝对路径
         */
        // 获取对应的系统
        String os = System.getProperty("os.name");
        // 如果是window系统
        if (os.toLowerCase().startsWith("win")) {
           registry.addResourceHandler("/fileData/**").addResourceLocations("file:" + windir);
        } else {
           registry.addResourceHandler("/fileData/**").addResourceLocations("file:" + lindir);
        }
  
    }
}

此时:我们访问IP地址:端口号/fileData/时,就相当于到了服务器D盘下的myFile文件夹中了。

注:此时默认的四个文件夹都失效了,如果想让默认的四个文件夹依然有效,那么可以在配置类中通过.addResourceHandler多次添加四个文件夹。

方式2:通过配置文件

# 设置当URI为/fileData/**时,才进过静态资源
# 注:如果设置为/**,那么表示任何访问都会经过静态资源路径
spring.mvc.static-path-pattern=/fileData/**
 
# 自定义路径
# 注:自定义路径时,默认的四个文件夹下中的“META-INF下的resoures文件夹”仍然有效,其他三个文件夹失效
# (此时:访问ip:端口号/fileData/时,相当于访问到了 “自定义的文件夹”和 “META-INF下的resoures文件夹”);
# 注:搜索文件时,自定义的文件夹的优先级要高于默认的四个文件夹
 spring.resources.static-locations=file:D:/myFile/
 
# 提示:如果我们显式地把自定义文件夹  和 默认的四个文件夹都写出来,那么都会有效(此时,优先级 从左至右 依次降低)
#spring.resources.static-locations = classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:D:/myFile/

三、文件读取和下载

1、读取

方式1:使用项目内路径读取,该路径只在开发工具中显示,类似:src/main/resources/resource.properties。只能在开发工具中使用,部署之后无法读取

@Test
    public void testReadFile2() throws IOException {
        File file = new File("src/main/resources/resource.properties");
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        String data = null;
        while((data = br.readLine()) != null) {
            System.out.println(data);
        }
        
        br.close();
        isr.close();
        fis.close();
    }

方式2:使用org.springframework.util.ResourceUtils,读取。在linux环境中无法读取。(不通用)因为ResourceUtils底层也是通过new File()方式读取的

@Test
    public void testReadFile3() throws IOException {
        File file = ResourceUtils.getFile("classpath:resource.properties");
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        String data = null;
        while((data = br.readLine()) != null) {
            System.out.println(data);
        }
        
        br.close();
        isr.close();
        fis.close();
    }

方式3:使用org.springframework.core.io.ClassPathResource,各种环境都能读取。(通用,推荐使用)

@Test
    public void testReadFile() throws IOException {
//        ClassPathResource classPathResource = new ClassPathResource("resource.properties");
        Resource resource = new ClassPathResource("resource.properties");
        InputStream is = resource.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String data = null;
        while((data = br.readLine()) != null) {
            System.out.println(data);
        }
        
        br.close();
        isr.close();
        is.close();
    }

方式4: 结合spring注解,使用org.springframework.core.io.ResourceLoader;类的注解。(通用)

    @Autowired
    ResourceLoader resourceLoader;
 
   @Test
    public String demo1(HttpServletRequest request) throws IOException {
        Resource resource = resourceLoader.getResource("classpath:demo.txt");
        InputStream is = resource.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String data = null;
        while((data = br.readLine()) != null) {
            System.out.println(data);
        }
 
        br.close();
        isr.close();
        is.close();
        return "ok";
    }
}

方式5:通用

@Test
    public String demo1(HttpServletRequest request) throws IOException {
        InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("demo.txt");
        InputStreamReader isr = new InputStreamReader(resourceAsStream);
        BufferedReader br = new BufferedReader(isr);
        String data = null;
        while((data = br.readLine()) != null) {
            System.out.println(data);
        }
 
        br.close();
        isr.close();
        resourceAsStream.close();
        return "ok";
    }

方式6:通用

 @Test
    public String demo1(HttpServletRequest request) throws IOException {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("demo.txt");
        InputStreamReader isr = new InputStreamReader(resourceAsStream);
        BufferedReader br = new BufferedReader(isr);
        String data = null;
        while((data = br.readLine()) != null) {
            System.out.println(data);
        }
 
        br.close();
        isr.close();
        resourceAsStream.close();
        return "ok";
    }

2、下载

直接通过浏览器访问上述默认四个路径下的文件或者自定义路径下文件时有的是下载方式有的是直接预览,比如图片、txt、pdf、视频是直接打开预览,而zip 、apk、docx、xlsx、ppt都是下载

如何解决直接预览改为下载文件

 @GetMapping("/download")
    public void download(HttpServletResponse response) {
        String fileName = "测试.txt";
        ClassPathResource resource = new ClassPathResource(fileName);
        InputStream is = null;
        try {
            is = resource.getInputStream();
 
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setHeader("Content-Disposition", "attachment; filename=\"" +
                    new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1) + "\"");
 
            OutputStream os = response.getOutputStream();
            FileCopyUtils.copy(is, os);
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

原生

@GetMapping("/download")
    public void download(HttpServletResponse response) {
        String fileName = "测试.txt";
        ClassPathResource resource = new ClassPathResource(fileName);
        InputStream is = null;
        try {
            is = resource.getInputStream();
 
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setHeader("Content-Disposition", "attachment; filename=\"" +
                    new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1) + "\"");
 
            byte[] buffer = new byte[1024];
 
            OutputStream os = response.getOutputStream();
            int len;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
 
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ignored) {
                }
            }
        }
    }

四、文件上传和回显

前面已经讲过如果访问资源、文件上传建议将其上传到特定的文件服务器,直接通过文件路径访问,或者jar包外指定的路径。然后通过配置映射访问

https://blog.csdn.net/qq_34491508/article/details/111618431

五、访问WebJar资源

使用Springboot进行web开发时,boot底层实际用的就是springmvc,项目中加入spring-boot-starter-web依赖,就会提供嵌入的tomcat以及mvc依赖,可以查看依赖树

Web前端使用了越来越多的JS或CSS,如jQuery, Backbone.js 和Bootstrap。一般情况下,我们是将这些Web资源拷贝到Java的目录下,通过手工进行管理,这种通方式容易导致文件混乱、版本不一致等问题。

WebJars是将这些通用的Web前端资源打包成Java的Jar包,然后借助Maven工具对其管理,保证这些Web资源版本唯一性,升级也比较容易。关于webjars资源,有一个专门的网站https://www.webjars.org/,我们可以到这个网站上找到自己需要的资源,在自己的工程中添加入maven依赖,即可直接使用这些资源了。

原理过程:查看引入的jar包

SpringBoot将对/webjars/**的访问重定向到classpath:/META-INF/resources/webjars/**

源码如下

public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if(!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
                CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
                if(!registry.hasMappingForPattern("/webjars/**")) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }
 
                String staticPathPattern = this.mvcProperties.getStaticPathPattern();
                if(!registry.hasMappingForPattern(staticPathPattern)) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }
 
            }
        }

所以可使用目录 localhost:8080/webjars/jquery/3.3.1/jquery.js访问静态资源

六、favicon.ico图标

如果在配置的静态资源目录中有favicon.ico文件,SpringBoot会自动将其设置为应用图标。

在Spring Boot的配置文件application.properites中可以添加配置项spring.mvc.favicon.enabled=false关闭默认的favicon,

七.欢迎页面

SpringBoot支持静态和模板欢迎页,它首先在静态资源目录查看index.html文件做为首页,被/**映射

参考地址SpringBoot资源文件的存放位置设置_justry_deng的博客-CSDN博客_springboot 文件路径


相关文章
|
1月前
|
JSON JavaScript 前端开发
springboot中使用knife4j访问接口文档的一系列问题
本文作者是一位自学前端两年半的大一学生,分享了在Spring Boot项目中使用Knife4j遇到的问题及解决方案,包括解决Swagger请求404错误、JS错误等,详细介绍了依赖升级、注解替换及配置修改的方法。
78 1
|
1月前
|
JSON JavaScript 前端开发
springboot中使用knife4j访问接口文档的一系列问题
本文介绍了在Spring Boot项目中使用Knife4j访问接口文档时遇到的一系列问题及其解决方案。作者首先介绍了自己是一名自学前端的大一学生,熟悉JavaScript和Vue,正在向全栈方向发展。接着详细说明了如何解决Swagger请求404错误,包括升级Knife4j依赖、替换Swagger 2注解为Swagger 3注解以及修改配置类中的代码。最后,针对报JS错误的问题,提供了删除消息转换器代码的解决方法。希望这些内容能对读者有所帮助。
304 5
|
1月前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
123 8
|
2月前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。
|
3月前
|
Java Spring
springboot静态资源目录访问,及自定义静态资源路径,index页面的访问
本文介绍了Spring Boot中静态资源的访问位置、如何进行静态资源访问测试、自定义静态资源路径和静态资源请求映射,以及如何处理自定义静态资源映射对index页面访问的影响。提供了两种解决方案:取消自定义静态资源映射或编写Controller来截获index.html的请求并重定向。
springboot静态资源目录访问,及自定义静态资源路径,index页面的访问
|
1月前
|
JavaScript 前端开发 Java
SpringBoot_web开发-webjars&静态资源映射规则
https://www.91chuli.com/ 举例:jquery前端框架
23 0
|
2月前
|
前端开发 Java
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
文章介绍了如何使用SpringBoot创建简单的后端服务器来处理HTTP请求,包括建立连接、编写Controller处理请求,并返回响应给前端或网址。
61 0
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
|
3月前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
50 6
|
3月前
|
存储 前端开发 Java
springboot文件上传和下载接口的简单思路
本文介绍了在Spring Boot中实现文件上传和下载接口的简单思路。文件上传通过`MultipartFile`对象获取前端传递的文件并存储,返回对外访问路径;文件下载通过文件的uuid名称读取文件,并通过流的方式输出,实现文件下载功能。
springboot文件上传和下载接口的简单思路
|
3月前
|
XML JSON Java
springboot文件上传,单文件上传和多文件上传,以及数据遍历和回显
本文介绍了在Spring Boot中如何实现文件上传,包括单文件和多文件上传的实现,文件上传的表单页面创建,接收上传文件的Controller层代码编写,以及上传成功后如何在页面上遍历并显示上传的文件。同时,还涉及了`MultipartFile`类的使用和`@RequestPart`注解,以及在`application.properties`中配置文件上传的相关参数。
springboot文件上传,单文件上传和多文件上传,以及数据遍历和回显