• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

使用multipart/form-data方式传递MultipartFile参数,实现服务间文件的传递

武飞扬头像
weixin_43202160
帮助1

目录

  • 一、代码实现
  • 二、MultipartFile工具类
  • 三、HttpClient使用
  • 四、参考链接

一、代码实现

1、A服务接收前端上传文件并发送至B服务
引入依赖
<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.13</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5.13</version>
        </dependency>
使用MultipartFile接收前端文件
  	@PostMapping("/import")
    @ApiOperation("文件上传")
    public Object importExcel(@RequestParam("file") MultipartFile file) {
        // 后续文件处理逻辑......
    }
调取第三方接口,发送 MultipartFile 文件
/**
     * 以post方式调用第三方接口,以form-data 形式  发送 MultipartFile 文件数据
     *
     * @param url           post请求url
     * @param fileParamName 文件参数名称
     * @param multipartFile 文件
     * @param paramMap      表单里其他参数
     * @return 响应结果
     */
    public static Object doPostFormData(String url, String fileParamName, MultipartFile multipartFile, Map<String, String> paramMap) {
        // 创建Http实例
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建HttpPost实例
        HttpPost httpPost = new HttpPost(url);
        // 请求参数配置
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000)
                .setConnectionRequestTimeout(10000).build();
        httpPost.setConfig(requestConfig);
        try {
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(StandardCharsets.UTF_8);
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

            String fileName = multipartFile.getOriginalFilename();
            // 文件流
            builder.addBinaryBody(fileParamName, multipartFile.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);
            //表单中其他参数
            for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                builder.addPart(entry.getKey(), new StringBody(entry.getValue(), ContentType.create("text/plain", Consts.UTF_8)));
            }
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            // 执行提交
            HttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回
                return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("调用HttpPost失败!"   e.toString());
        } finally {
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    log.error("关闭HttpPost连接失败!");
                }
            }
        }
        return null;
    }
学新通
2、B服务接收文件
    @PostMapping(value = "/import", headers = "content-type=multipart/form-data")
    @ApiOperation("接收上传文件")
    public Result<Object> importExcel(HttpServletRequest request, HttpServletResponse response) {
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        commonsMultipartResolver.setDefaultEncoding("utf-8");
        if (commonsMultipartResolver.isMultipart(request)){
            MultipartHttpServletRequest mulReq = (MultipartHttpServletRequest) request;
            Map<String, MultipartFile> map = mulReq.getFileMap();
          	// fileParamName
            MultipartFile multiFile = map.get("fileParamName");
            // 后续文件处理逻辑......
        }
        return new Result<>().error("请求内容有误!");
    }

二、MultipartFile工具类

  • 简介:MultipartFile是SpringMVC提供简化上传操作的工具类,在不使用框架之前,都是使用原生的HttpServletRequest来接收上传的数据,文件是以二进制流传递到后端的,然后需要我们自己转换为File类。使用了MultipartFile工具类之后,我们对文件上传的操作就简便许多了。
  • MultipartFile工具类的接口方法
package org.springframework.web.multipart;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import org.springframework.core.io.InputStreamSource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.util.FileCopyUtils;

public interface MultipartFile extends InputStreamSource {
    //getName() 返回参数的名称
    String getName();
    //获取源文件的昵称
    @Nullable
    String getOriginalFilename();
    //getContentType() 返回文件的内容类型
    @Nullable
    String getContentType();
    //isEmpty() 判断是否为空,或者上传的文件是否有内容
    boolean isEmpty();
    //getSize() 返回文件大小 以字节为单位
    long getSize();
    //getBytes() 将文件内容转化成一个byte[] 返回
    byte[] getBytes() throws IOException;
    //getInputStream() 返回InputStream读取文件的内容
    InputStream getInputStream() throws IOException;

    default Resource getResource() {
        return new MultipartFileResource(this);
    }
    //transferTo是复制file文件到指定位置(比如D盘下的某个位置),不然程序执行完,文件就会消失,程序运行时,临时存储在temp这个文件夹中
    void transferTo(File var1) throws IOException, IllegalStateException;

    default void transferTo(Path dest) throws IOException, IllegalStateException {
        FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
    }
}
学新通
  • InputStreamSource 这个接口本质上返回的还是一个InputStream 流对象
package org.springframework.core.io;

import java.io.IOException;
import java.io.InputStream;

public interface InputStreamSource {
	//定位并打开资源,返回资源对应的输入流。
    //每次调用都会返回新的输入流,调用者在使用完毕后必须关闭该资源。 
    InputStream getInputStream() throws IOException;
}

三、HttpClient使用

  • 使用httpclient,需要下载httpclient-4.5.jar、httpmime-4.5.jar两个包,下载地址为:http://hc.apache.org/downloads.cgi 大致看了下源码,其实也是使用字符拼接,只是封装后使用起来更简洁方便一些。、
  • httpclient需要注意的4点:
  • 1.HttpClient4.3版本往后,原来的MultipartEntity过时不建议再使用了,替换成新的httpmime下面的MultipartEntityBuilder
  • 2.multipartEntity 最好设置contentType和boundary,不然会导致后面接收文件时的第一种方法接收不到文件报错。
  • 3.使用addBinaryBody的坑:addBinaryBody 有6种不同用法,一般都是如下代码所示上传File即可,但是当传byte[]字节数组时,必须使用4参传值,且第四参必须带后缀名,例如:entityBuilder.addBinaryBody(“file”,new byte[]{},ContentType.DEFAULT_BINARY,“fileName.jpg”);否则会导致接收文件时getFileNames()为空。
  • 4.不使用addBinaryBody,也可以直接使用addPart,先把文件转换成FileBody就可以了
  • contentType使用【multipart/form-data】:它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件,
  • boundary:请求体中的boundary参数指定的就是分隔体,请求参数之间需要通过分隔体分隔,不然就会被识别成一个参数。

四、参考链接

  • https://blog.csdn.net/lexuansweet/article/details/122967948

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfcfcc
系列文章
更多 icon
同类精品
更多 icon
继续加载