• SpringBoot如何上传文件


    [版权申明] 非商业目的注明出处可自由转载
    出自:shusheng007

    概述

    今天聊点实操类的小知识吧,没啥技术含量,但架不住实用…

    后端开发过程中偶尔会遇到文件的接收和上传的业务场景。接收呢是前端将文件传给后端,后端负责接收处理,上传呢是后端把文件上传到其他服务或者平台上。这两种场景下在SpringBoot中如何实现呢?

    现代Java开发中,各种框架和三方库的封装使得各种常用功能已经简化到在不知其所以然的情况下也能完成了,不过我们还是要稍微提一下原理,使文章显得更加的专业和高大上,哈哈…。我们通常文件的上传实用HTTP的POST方法,Content-Type 为multipart/form-data类型的方式。我们日常比较熟悉的Content-Type是application/json,用来传递Json格式的数据,而对 multipart/form-data却不一定熟悉。

    下面这个片段就是multipart/form-data请求体,是不是感觉很复杂啊,我多年前第一次看见也觉得好复杂,当时还不会使用封装好的第三方Http客户端,然后就是使用原始的来构建,哎, 往事不堪回首…

    POST /upload?upload_progress_id=12344 HTTP/1.1
    Host: localhost:3000
    Content-Length: 1325
    Origin: http://localhost:3000
    ... other headers ...
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L
    
    ------WebKitFormBoundaryePkpFF7tjBAqx29L
    Content-Disposition: form-data; name="MAX_FILE_SIZE"
    
    100000
    ------WebKitFormBoundaryePkpFF7tjBAqx29L
    Content-Disposition: form-data; name="uploadedfile"; filename="hello.o"
    Content-Type: application/x-object
    
    ... contents of file goes here ...
    ------WebKitFormBoundaryePkpFF7tjBAqx29L--
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    ----WebKitFormBoundaryePkpFF7tjBAqx29L 是每一part的分割符,必须以--开头,请求体最后也必须以--结尾,值可以是任意的。大体了解一下multipart/form-data的请求格式就好啦,现在你都不用自己去手写,都被框架给封装了,你只要知道你要上传的文件就是其中的一个part就好了。

    接收文件

    在Springboot中接收前端上传的文件很简单,在HTTP的Post方法中使用MultipartFile接收就ok了,如下代码所示

    @PostMapping("/uploadFile")
    public AjaxResult upload(@RequestParam("file") MultipartFile file, @RequestParam("other") String other) {
         ...
    }
    
    • 1
    • 2
    • 3
    • 4

    那个如果你除了文件还有其他参数,那就使用@RequestParam继续接收,有几个写几个就好。

    上传文件

    这个就比较麻烦点了,我们以RestTemplate来实现

    1. 设置Content-Type为multipart/form-data
     HttpHeaders headers = new HttpHeaders();
     headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    
    • 1
    • 2

    第二句代码就是设置http请求的content-type 为multipart/form-data

    1. 构建请求体
     MultiValueMap body = new LinkedMultiValueMap<>();
     body.add("file",new FileSystemResource(targetFile));
     body.add("param","其他参数");
    
     HttpEntity> requestEntity = new HttpEntity<>(body,headers);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    值得注意的是加到body里的需要一个Resource类型,我们这里使用File类型的targetFile构建了FileSystemResource。除了要上传的文件,我们还可以往body里面添加其他参数,像这里的param参数。

    最后使用第一步与这一步的数据构建一个requestEntity

    1. 发起请求

    通过上面两步已经构建了发起post请求的参数了,我们使用RestTemplate发起请求就好了

     try {
         ResponseEntity response = restTemplateBuilder
                 .basicAuthentication(AUTH_USER,AUTH_PASSWORD)
                 .build()
                 .postForEntity(UPLOAD_URL,requestEntity,String.class);
         return response.getBody();
     } catch (RestClientException e) {
         log.info("上传文件失败:{}",e.getMessage());
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    值得注意的是,我们这里使用了RestTemplateBuilder来构建RestTemplate,而且通过basicAuthentication设置了basic auth。如果你要上传的平台没有要求basic auth鉴权,那么去掉就可以了。

    gitbub源码

    你可以在这里:文件上传示例 找到完整的源码,记得点下小星星,那样就不怕找不到了…

    结论

    干…

  • 相关阅读:
    计算机毕业设计Java幼儿健康管理系统(系统+程序+mysql数据库+Lw文档)
    Qt编写物联网管理平台48-特色功能设计
    小程序长期订阅
    ApiFile配置环境
    Vue前端面试题
    第20篇 Vue命令简介
    YOLO系列总结:YOLOv1, YOLOv2, YOLOv3, YOLOv4, YOLOv5, YOLOX
    Docker常用命令
    查看当前所有的数据库
    Ubuntu 环境配置 Minecraft 基岩版服务器
  • 原文地址:https://blog.csdn.net/ShuSheng0007/article/details/126516866