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
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
要实现Spring Boot Vue头像上传回显,可以按照以下步骤进行操作。 1. 前端页面实现图片上传 在Vue组件中添加一个图片上传组件,使用element-ui的上传组件(el-upload)。具体代码如下: ```html <template> <el-upload class="avatar-uploader" action="/api/upload" :show-file-list="false" :on-success="handleSuccess" :before-upload="beforeUpload"> <img v-if="imageUrl" :src="imageUrl" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </template> <script> export default { data() { return { imageUrl: '' } }, methods: { beforeUpload(file) { // 限制文件类型和大小 const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' if (!isJPG) { this.$message.error('上传头像图片只能是 JPG 或 PNG 格式!') return false } const isLt2M = file.size / 1024 / 1024 < 2 if (!isLt2M) { this.$message.error('上传头像图片大小不能超过 2MB!') return false } return true }, handleSuccess(response) { if (response.code === 200) { this.imageUrl = response.data this.$emit('update:avatar', response.data) // 通知父组件更新头像 } else { this.$message.error(response.msg) } } } } </script> <style scoped> .avatar-uploader { display: flex; align-items: center; justify-content: center; width: 120px; height: 120px; border-radius: 50%; overflow: hidden; background-color: #f5f5f5; } .avatar { width: 100%; height: 100%; object-fit: cover; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; } </style> ``` 在上传图片前,使用beforeUpload方法对文件类型和大小进行限制。在上传成功后,将服务器返回的图片地址保存到imageUrl中,并通过$emit方法通知父组件更新头像。 2. 后端实现图片上传Spring Boot中实现文件上传需要使用MultipartFile类型接收前端传来的文件。具体代码如下: ```java @RestController @RequestMapping("/api") public class FileUploadController { @Value("${file.upload.path}") private String filePath; // 文件保存路径 @PostMapping("/upload") public Result upload(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return Result.fail("上传失败,请选择文件"); } String fileName = file.getOriginalFilename(); String suffix = fileName.substring(fileName.lastIndexOf(".")); String newFileName = UUID.randomUUID().toString() + suffix; File dest = new File(filePath + newFileName); try { file.transferTo(dest); return Result.success("上传成功", "/uploads/" + newFileName); } catch (IOException e) { e.printStackTrace(); } return Result.fail("上传失败"); } } ``` 在文件上传接口中,通过@Value注解从配置文件中读取文件保存路径,然后使用MultipartFile类型接收前端传来的文件。接收到文件后,使用UUID生成新的文件名,将文件保存到指定路径,并返回服务器存储的文件地址。 3. 更新用户头像 在Vue组件中,通过接收父组件传来的用户信息,将头像地址赋值给imageUrl。在头像上传成功后,通过$emit方法通知父组件更新头像。具体代码如下: ```html <template> <div> <avatar-upload :avatar="user.avatar" @update:avatar="updateAvatar"></avatar-upload> <el-button type="primary" @click="updateUser">更新用户信息</el-button> </div> </template> <script> import AvatarUpload from '@/components/AvatarUpload.vue' export default { components: { AvatarUpload }, props: { user: { type: Object, default: () => ({}) } }, data() { return { form: { id: '', username: '', password: '', nickname: '', avatar: '' } } }, created() { this.form = { ...this.user } }, methods: { updateAvatar(avatar) { this.form.avatar = avatar }, updateUser() { // 调用后端接口更新用户信息 } } } </script> ``` 在更新用户信息的方法中,调用后端接口将用户信息更新到数据库中。 ```java @RestController @RequestMapping("/api") public class UserController { @Autowired private UserService userService; @PostMapping("/updateUser") public Result updateUser(@RequestBody User user) { userService.updateUser(user); return Result.success("更新成功"); } } ``` 在UserService中实现更新用户信息的方法。 ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public void updateUser(User user) { userMapper.updateById(user); } } ``` 以上就是Spring Boot Vue头像上传回显的实现方法。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序三两行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值