springboot 中做MultipartFile文件跨服务传输的方案汇总

方案一:一句话总结,将前端传入的MultipartFile文件转为字节流发送到其他服务。

可以用RestTemplate也可以用HttpClient,以下是两种方法的说明。

 

用RestTemplate做

1.如果用RestTemplate的话首先需要把RestTemplate交给spring去管理所以先来一个配置类。

@Configuration
@SuppressWarnings("all")
public class RestTemplateConfig {

  @Autowired
  RestTemplateBuilder builder;

  @Bean
  public RestTemplate restTemplate() {
    return builder.build();
  }
}

2.RestTemplate远程调用文件传输

这里有几个要注意的地方

1.必须重写否则传输时报错

ByteArrayResource byteArrayResource = new ByteArrayResource(file.getBytes()) {
      @Override
      public String getFilename() {
        return file.getOriginalFilename();
      }
    };

2.设置请求头因为就在模拟前端发送上传文件的请求所以请求头必须是multipart/form-data

代码:

@Autowired
private RestTemplate restTemplate;

private String gettestRestTemplate(MultipartFile file, String url) throws IOException {
    HttpHeaders headers = new HttpHeaders();
    MediaType type = MediaType.parseMediaType("multipart/form-data");
    headers.setContentType(type);
    MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
    ByteArrayResource byteArrayResource = new ByteArrayResource(file.getBytes()) {
      @Override
      public String getFilename() {
        return file.getOriginalFilename();
      }
    };
    form.add("file", byteArrayResource);
    form.add("filename", file.getOriginalFilename());
    //用HttpEntity封装整个请求报文
    HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers);

    String flag = restTemplate.postForObject(url, files, String.class);

    return flag;
  }

用HttpClient做

1.使用httpclient的话首先要引入pom文件坐标。

 <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.5.6</version>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpmime</artifactId>
      <version>4.5.6</version>
    </dependency>

3.HttpClient远程调用文件传输

1.httpclient这段代码有要用的小伙伴直接粘过去就能用
注意一下返回值自己改一下就行execute.getEntity()

@SneakyThrows
  private String gettesthttpclient(MultipartFile file, String url) {
    CloseableHttpClient httpclient = HttpClients.createDefault();
    RequestConfig requestConfig = RequestConfig.custom()
        .setConnectionRequestTimeout(10000)
        .setConnectTimeout(5000)
        .build();
    HttpPost httpPost = new HttpPost(url);
    MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
    // 解决中文文件名乱码问题
    entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
    entityBuilder.setCharset(Consts.UTF_8);
    ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), Consts.UTF_8);
    entityBuilder.addBinaryBody("file", file.getInputStream(), ContentType.DEFAULT_BINARY, file.getOriginalFilename());
    httpPost.setEntity(entityBuilder.build());
    httpPost.setConfig(requestConfig);
    HttpResponse execute = httpclient.execute(httpPost);
    String flag = EntityUtils.toString(execute.getEntity());
    return flag;
  }

总结:远程调用使用了RestTemplate和httpclient也可以使用feign,但是RestTemplate和feign大文件会OOM(所以适用于小文件传输,约在1G以下),httpclient不会。

方案二:一句话总结,将前端传入的MultipartFile通过临时文件转为FileSystemResource,再将临时文件删除

最终解决方案:将图片放在一个temp文件夹,方便统一删除。

@RequestMapping("/upload")
public void postData(@RequestParam("file") MultipartFile file) throws IOException {
      String url = "https://localhost:8080/upload";
      MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
      bodyMap.add("file", new FileSystemResource(convert(file)));
      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.MULTIPART_FORM_DATA);
      HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(bodyMap, headers);
      RestTemplate restTemplate = new RestTemplate();
      ResponseEntity<String> response = restTemplate.exchange(url,
              HttpMethod.POST, requestEntity, String.class);
    }
  public static File convert(MultipartFile file)
  {    
    File convFile = new File("temp_image", file.getOriginalFilename());
    if (!convFile.getParentFile().exists()) {
            System.out.println("mkdir:" + convFile.getParentFile().mkdirs());
    }
    try {
        convFile.createNewFile();
          FileOutputStream fos = new FileOutputStream(convFile);
            fos.write(file.getBytes());
            fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return convFile;
 }


转自:关于springboot 中使用httpclient或RestTemplate做MultipartFile文件跨服务传输的问题-云海天教程

Springboot 中使用 RestTemplate 向另一个 RESTful api 请求 multipart file 报错_thothsun 的博客-CSDN博客

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值