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 文件路径


相关文章
|
5天前
|
Java 数据库连接 mybatis
springboot访问jsp页面变成直接下载?
springboot访问jsp页面变成直接下载?
82 0
|
5天前
|
XML Java 数据库连接
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
54 0
|
5天前
|
存储 Java 对象存储
springboot配置阿里云OSS存储实现文件上传下载功能
【1月更文挑战第1天】springboot配置阿里云OSS存储实现文件上传下载功能
720 2
|
5天前
|
缓存 Java Sentinel
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
|
3天前
|
XML JavaScript 前端开发
springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】
springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】
|
5天前
|
NoSQL Java Redis
springboot之RedisTemplate的访问单机,哨兵,集群模式
以上是配置RedisTemplate以连接到单机、哨兵和集群模式的示例。在实际应用中,还可以根据需求配置连接池、序列化方式、超时等其他参数。
38 0
|
5天前
|
Java Spring
spring boot访问接口报500
spring boot访问接口报500
13 2
|
5天前
|
前端开发 JavaScript Java
SpringBoot解决跨域访问的问题
本文介绍了跨域访问的概念及其解决方案。同源策略规定浏览器限制不符合协议、Host和端口的请求,导致跨域访问被禁止。为解决此问题,文中提出了三种策略:1) 前端利用HTML标签的特性(如script、iframe)和JSONP、postMessage规避同源策略;2) 通过代理,如nginx或nodejs中间件,使得所有请求看似来自同一源;3) CORS(跨域资源共享),通过设置HTTP响应头允许特定跨域请求。在SpringBoot中,实现CORS有四种方式,包括使用CorsFilter、重写WebMvcConfigurer、CrossOrigin注解以及直接设置响应头。
|
5天前
|
前端开发 Java Apache
Spring Boot文件上传与下载讲解与实战(超详细 附源码)
Spring Boot文件上传与下载讲解与实战(超详细 附源码)
494 0
|
5天前
|
算法 安全 Java
服务器启动 SpringBoot 后访问特别慢的解决方案
服务器启动 SpringBoot 后访问特别慢的解决方案
34 1