锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. Spring Boot 中文件上传

Spring Boot 中文件上传

0
  • 软件开发
  • 发布于 2024-08-16
  • 0 次阅读
黄健
黄健

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net

Spring Boot 中文件上传

  • 一、MultipartFile

  • 二、单文件上传案例

  • 三、多文件上传案例

  • 四、Servlet 规范

  • 五、Servlet 规范实现文件上传

  • 上传文件大家用的最多的就是 Apache Commons FileUpload,这个库使用非常广泛。Spring Boot3 版本中已经不能使用了。代替它的是 Spring Boot 中自己实现的文件上传。

  • Spring Boot 上传文件现在变得非常简单。提供了封装好的处理上传文件的接口 MultipartReslover,用于解析上传文件的请求,它的内部实现类 StandardServletMultipartResolver。之前常用的 CommonsMultipartResolver 不能使用了。 CommonsMultipartResolver 是使用 Apache Commons File Upload 库时的处理类。

一、MultipartFile

  • StandardServletMultipartResolver 内部封装了读取 POST 请求的请求体中的数据,也就是文件内容。我们只需要在 Controller 的方法中加入形参 @ReqestParam("参数名") MultipartFile file。MultipartFile 表示上传的文件,其提供了方便的方法保存文件到磁盘。MultipartFile API 如下:

    public interface MultipartFile extends InputStreamSource {
        String getName();//返回参数的名称
        @Nullable
        String getOriginalFilename();//获取上传文件的名称
        @Nullable
        String getContentType();//返回文件的内容类型
        boolean isEmpty();//判断是否为空,或者上传的文件是否有内容
        long getSize();//返回文件大小 以字节为单位
        byte[] getBytes() throws IOException;//将文件内容转化成一个byte[] 返回
        InputStream getInputStream() throws IOException;//返回InputStream读取文件的内容
        default Resource getResource() {
            return new MultipartFileResource(this);
        }
        //保存上传文件到目标Dest中
        void transferTo(File dest) throws IOException, IllegalStateException;
        default void transferTo(Path dest) throws IOException, IllegalStateException {
            FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
        }
    }
    

二、单文件上传案例

  • 创建两个静态页面,一个用来上传文件(使用表单的方式),另一个用来显示文件上传成功。(注意:静态资源放在 static 目录下,否则访问不到资源)

    • 使用表单的方式上传文件必须满足的三个要求:
      • ① enctype=“multipart/form-data”
      • ② method=“post”
      • ③
    <!-- 文件名:uploadfile.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>上传文件</title>
    </head>
    <body>
      <h3>上传文件</h3>
      <div>
    
      </div>
      <form action="uploadFile" enctype="multipart/form-data" method="post">
          选择需要上传的文件:<input type="file" value="选择文件" > <br>
          <input type="submit" value="上传文件">
      </form>
    </body>
    </html>
    
    <!-- 文件名:upload_success.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件上传成功</title>
    </head>
    <body>
      <h3>文件上传成功</h3>
    </body>
    </html>
    
  • 编写controller方法获取请求,然后保存文件。

    @Controller
    public class UploadFileController {
        @PostMapping("/uploadFile")
        public String uploadFile(@RequestParam("uploadFile") MultipartFile multipartFile) throws IOException {
            //首先判断上传的文件是否为空
            if (!multipartFile.isEmpty()) {
                String suffix = ".unknown";//初始文件后缀为不知道
                String name = multipartFile.getOriginalFilename();//获取上传的文件名
                System.out.println(name);
                //获取文件的后缀
                if (name != null && name.indexOf(".") > 0) {
                    suffix = name.substring(name.indexOf("."));
                }
                String dest = UUID.randomUUID() + suffix;//生成保存的文件名
                multipartFile.transferTo(new File("G:/files/" + dest));//保存文件到指定位置
            }
            //防止刷新,重复上传
            return "redirect:/upload_success.html";
        }
    }
    
  • 编写错误页面

    • 在 SpringBoot 中 /static/error/5xx.html 文件 ===> 如果出现 5xx 的错误自动跳转到整个页面。
    • 在 SpringBoot 中 /static/error/4xx.html 文件 ===> 如果出现 4xx 的错误自动跳转到整个页面 。
    <!-- 文件名:5xx.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>出现了 5XX 错误!!!</h3>
    </body>
    </html>
    
    <!-- 文件名:4xx.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>出现了 4XX 错误!!!</h3>
    </body>
    </html>
    
  • 设置上传文件的大小

    • Spring Boot 默认单个文件最大支持1M,一次请求最大10M。改变默认值,需要修改 application.yml 配置文件。file-size-threshold 超过指定大小,直接写文件到磁盘,不在内存处理。
  • 不能只考虑SpingBoot每次请求的文件最大大小,还需要设置服务器每次请求的大小。

三、多文件上传案例

  • 多文件上传,在接收文件参数部分有所改变 MultipartFile[] files。循环遍历数组解析每一个上传的文件。

  • 前端通过 form 表单上传多文件。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>上传文件</title>
    </head>
    <body>
      <h3>上传文件</h3>
      <div>
    
      </div>
      <form action="uploadFile" enctype="multipart/form-data" method="post">
          选择需要上传的文件 1:<input type="file" value="选择文件" > <br>
          选择需要上传的文件 2:<input type="file" value="选择文件" > <br>
          选择需要上传的文件 3:<input type="file" value="选择文件" > <br>
          <input type="submit" value="上传文件">
      </form>
    </body>
    </html>
    

四、Servlet 规范

  • Servlet3.0 规范中,定义了 Jakarta.servlet.http.Part 接口处理 mulitipart/form-data POST 请求中接收到的表单数据。有了 Part 对象,其 write() 方法将上传文件保存到服务器本地的磁盘中。

  • 在 HttpServletRequest 接口中引入的新方法:

    • getParts():返回 Part 对象的集合。
    • getPart(字符串名称):检索具有给定名称的单个 Part 对象。
  • Spring Boot3 使用的 Servlet 规范是基于 5 的,所以上传文件使用的就是 Part 接口。

  • StandardServletMultipartResolver 对 Part 接口进行的封装,实现基于 Servlet 规范的文件上传。

    public interface Part {
        InputStream getInputStream() throws IOException;//获取输入流用于检索文件的内容
        String getContentType();//获取文件内容类型
        String getName();//获取file控件的name属性
        String getSubmittedFileName();//获取上传文件名Servlet3.1 Tomcat8.0实现
        long getSize();//获取上传文件的大小
        void write(String fileName) throws IOException; //将文件内容写入指定的磁盘位置
        void delete() throws IOException;//删除Part数据和临时目录数据,默认会删除
        String getHeader(String name);//获取指定请求头
        Collection<String> getHeaders(String name);//获取指定header名称的集合数据
        Collection<String> getHeaderNames();//获取所有请求头的名称
    }
    

五、Servlet 规范实现文件上传

@PostMapping("/files")
    public String upload(HttpServletRequest request){
        try {
            for (Part part : request.getParts()) {
                String fileName = extractFileName(part);
                part.write(fileName);
            }
        } catch (IOException | ServletException e) {
            throw new RuntimeException(e);
        }
        return "redirect:/upload_success.html";
    }
    private String extractFileName(Part part) {
        String contentDis = part.getHeader("content-disposition");
        String[] items = contentDis.split(";");
        for (String s : items) {
            if (s.trim().startsWith("filename")) {
                return s.substring(s.indexOf("=") + 2, s.length()-1);
            }
        }
        return "";
    }
  • 上传文件包含 header 头 content-disposition,类似如下的内容,可获取文件原始名称。
    • form-data; name=“dataFile”;filename=“header.png”
  • application.yml 文件,可配置服务器存储文件位置,例如:
    • spring.servlet.multipart.location=G:/files/
标签: #Spring Boot 173 #JAVA 991 #软件开发 1171
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.