使用RestTemplate 调用远程接口上传文件方式

目录
  • RestTemplate 调用远程接口上传文件
    • 问题描述
    • 解决方法
      • 第一种方式
      • 第二种方式
  • RestTemplate调用远程接口添加请求头

RestTemplate 调用远程接口上传文件

问题描述

第三方写了一个文件上传的接口,该接口的请求方式为Post请求,请求参数全部是以form-data表单形式进行提交,包含三个参数

  • 第一个:cookie(字符串类型)
  • 第二个:seqNo(字符串类型)
  • 第三个:file(文件类型)

解决方法

使用传统的Spring Cloud的Feign组件在调用远程接口实现文件上传时有时会出现异常错误,可考虑使用下述两种方式文件上传

第一种方式

使用RestTemplate进行调用

import org.springframework.core.io.InputStreamResource;
import java.io.InputStream;
public class CommonInputStreamResource extends InputStreamResource {
    private long length;
    private String fileName;
    public CommonInputStreamResource(InputStream inputStream, long length, String fileName) {
        super(inputStream);
        this.length = length;
        this.fileName = fileName;
    }

    /**
     * 覆写父类方法
     * 如果不重写这个方法,并且文件有一定大小,那么服务端会出现异常
     * {@code The multi-part request contained parameter data (excluding uploaded files) that exceeded}
     */
    @Override
    public String getFilename() {
        return fileName;
    }

    /**
     * 覆写父类 contentLength 方法
     * 因为 {@link org.springframework.core.io.AbstractResource#contentLength()}方法会重新读取一遍文件,
     * 而上传文件时,restTemplate 会通过这个方法获取大小。然后当真正需要读取内容的时候,发现已经读完,会报如下错误。
     */
    @Override
    public long contentLength() {
        long estimate = length;
        return estimate == 0 ? 1 : estimate;
    }

    public void setLength(long length) {
        this.length = length;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
}
try{
    String applySeqNo = "123456";
    String cookie="654321";
    File file=new File("E:\\1.rar");
    FileInputStream fileInputStream=new FileInputStream(file);

    //请求头设置为MediaType.MULTIPART_FORM_DATA类型
    HttpHeaders requestHeaders = new HttpHeaders();
    requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

    //构建请求体
    MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
    CommonInputStreamResource commonInputStreamResource = null;
    try {
        commonInputStreamResource = new CommonInputStreamResource(fileInputStream,file.length(),file.getName());
    } catch (Exception e) {
        log.error("文件输入流转换错误",e);
    }
    requestBody.add("cookie", cookie);
    requestBody.add("seqNoFile", applySeqNo);
    requestBody.add("file",commonInputStreamResource);
    HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(requestBody, requestHeaders);

    //直接调用远程接口
    ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://xxx.xxx.xxx.xxx:8080/test/upload",requestEntity, String.class);
    System.out.println("返回结果:"+responseEntity.getBody())
}catch (Exception e){
    log.error("远程调用出现异常:", e);
}

第二种方式

Spring Cloud Feign组件 + MultiValueMap + CommonInputStreamResource

CommonInputStreamResource对象的构造在上面已经实现了这里就不再重复构造,沿用上面的那个就行

feign接口

@Component
@FeignClient(name = "taxRecodes", url = "${spider.url}", qualifier = "TaxRecodeFeignClient",fallback = TaxRecodeFallBack.class)
public interface TaxRecodeFeignClient {
    /**
     * 单证申请-合同信息表附件上传
     */
    @PostMapping(value = "/attachFile/upload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String attachFileUpload(MultiValueMap<String, Object> multiValueMap);
}

请求部分

@PostMapping("/upload")
public void upload(){
    try {
        File file=new File("E:\\1.rar");
        FileInputStream fileInputStream=new FileInputStream(file);
        CommonInputStreamResource commonInputStreamResource = null;
        try {
            commonInputStreamResource = new CommonInputStreamResource(fileInputStream,fileInputStream.available(),file.getName());
        } catch (Exception e) {
            log.error("文件输入流转换错误:",e);
        }
        MultiValueMap<String, Object> dto=new LinkedMultiValueMap<String, Object>();
        dto.add("cookie","xxx");
        dto.add("file",commonInputStreamResource);
        dto.add("seqNoFile","xxx");

        String returnInfo = taxRecodeFeignClient.attachFileUpload(dto);
        JSONObject returnInfoJsonObject = JSONObject.parseObject(returnInfo);
    }catch (Exception e){
        log.error("异常:",e);
    }
}

RestTemplate调用远程接口添加请求头

项目中我们经常会碰到与第三方系统对接,通过调用第三方系统中的接口来集成服务,为了接口的安全性都为加一些验证,比如:

basic、authority等,通过请求头添加authrization的机制比较容易接入,从第三方系统获取到authorization,然后请求接口时在请求头上带上获取到的authorization,说了怎么多不如直接上代码更容易理解。

// 获取第三方的authorization
String auth= OAuthContentHelper.getAuthorizationHeader();
HttpHeaders requestHeader=new HttpHeaders();
// 将获取到的authorization添加到请求头
requestHeader.add(AuthConstants.AUTHORIZATION_HEADER,auth);
// 构建请求实体
HttpEntity<Object> requestEntity=new HttpEntity(requestParam,requestHeaders);
// 使用restTemplate调用第三方接口
restTemplate.exchage(url,HttpMethod.POST,requestEntity,responseClass);

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring学习笔记之RestTemplate使用小结

    前言 作为一个Java后端,需要通过HTTP请求其他的网络资源可以说是一个比较常见的case了:一般怎么做呢? 可能大部分的小伙伴直接捞起Apache的HttpClient开始做,或者用其他的一些知名的开源库如OkHttp, 当然原生的HttpURLConnection也是没问题的 本篇博文则主要关注点放在Sprig的生态下,利用RestTemplate来发起Http请求的使用姿势 I. RestTempalate 基本使用 0. 目标 在介绍如何使用RestTemplate之前,我们先抛出一些

  • 使用restTemplate远程调controller路径取数据

    目录 restTemplate远程调controller路径取数据 首先要写相关配置类,举例: 然后调目标cotroller层,比如目标cotroller层为 需要用post的方法去调 再比如目标controller层为 需要用get的方法去调 通过Spring的RestTemplate进行跨模块调用 相关代码如图下所示: 相关代码可参考图下所示: 运行结果如下所示: restTemplate远程调controller路径取数据 Spring的RestTemplate提供了很多对HTTP met

  • 基于RestTemplate的使用方法(详解)

    1.postForObject :传入一个业务对象,返回是一个String 调用方: BaseUser baseUser=new BaseUser(); baseUser.setUserid(userid); baseUser.setPass(pass); String postForObject = restTemplate.postForObject(this.getURL()+"/user/login", baseUser, String.class); return postF

  • 关于springboot 中使用httpclient或RestTemplate做MultipartFile文件跨服务传输的问题

    大家好,因为近期做需求中遇到了文件上传这个东西,而且我这个还是跨服务去传输文件的所以我这边使用了httpclient和RestTemplate去做,但是最后还是用的httpclient.feign和RestTemplate在超大文件下会OOM所以适用于小文件传输我这边测试的在1G以下.httpclient好像是无限哈哈哈.(具体多少大家有时间可以去测一下) 1.被调用服务的Controller 1.这块使用@RequestParam("file")或者@RequestPart(&quo

  • 使用RestTemplate 调用远程接口上传文件方式

    目录 RestTemplate 调用远程接口上传文件 问题描述 解决方法 第一种方式 第二种方式 RestTemplate调用远程接口添加请求头 RestTemplate 调用远程接口上传文件 问题描述 第三方写了一个文件上传的接口,该接口的请求方式为Post请求,请求参数全部是以form-data表单形式进行提交,包含三个参数 第一个:cookie(字符串类型) 第二个:seqNo(字符串类型) 第三个:file(文件类型) 解决方法 使用传统的Spring Cloud的Feign组件在调用远

  • 微服务之间如何通过feign调用接口上传文件

    具体需求: 我们的项目是基于springboot框架的springcloud微服务搭建的,后端服务技术层面整体上分为business服务和core服务,business服务用于作为应用层,直接连接客户端,通常用于聚合数据,core服务用来客户端具体操作不同需求来控制数据库,文件上传是通过客户端上传接口,通过business服务,由服务端调用feign接口,也是第一次做这种文件中转,遇到各种问题,下面是我自己的解决方案,不喜勿喷,代码小白一枚; 一.core服务层接口@requestmapping

  • 详解使用php调用微信接口上传永久素材

    功能需求 公司新开的公众号需要将公司平台现在的所有精品文章都导入,手动导入会有很多的工作量,所以采用自动化同步文章的方式来达到效果 开发说明 微信open api提供了新增永久素材的接口,本次功能是基于这个接口进行数据同步的 使用到的接口 获取永久素材列表接口:material/batchget_material 新增永久素材接口:material/add_news 新增媒体文件接口:material/add_material 图文类型 单图文(要求有默认的封面,需要提前上传到微信公众号后台)

  • JavaScript中三种异步上传文件方式

    异步上传文件是为了更好的用户体验,是每个前端必须掌握的技能.这里我提出三点有关异步文件上传的方式. 使用第三方控件,如Flash,ActiveX等浏览器插件上传. 使用隐藏的iframe模拟异步上传. 使用XMLHttpRequest2来实现异步上传. 第一种使用浏览器插件上传,需要一定的底层编码功底,在这里我就不讲了,以免误人子弟,提出这点大家可以自行百度. 第二种使用隐藏的iframe模拟异步上传.为什么在这里说的是模拟呢?因为我们其实是将返回结果放在了一个隐藏的iframe中,所以才没有使

  • element-ui配合node实现自定义上传文件方式

    目录 element-ui配合node实现自定义上传文件 自定义elementui上传文件及携带参数 下面是一个简单的上传标签 具体实现 携带参数 element-ui配合node实现自定义上传文件 某些情况下,使用element-ui的upload组件默认上传无法满足我们的需求,so-今天主要介绍如何使用element-ui实现自定义上传,以及后端如何接收上传的文件信息和其他信息,根据element-ui文档,http-request可以自定义上传方法,会覆盖掉默认的上传. 首先我们来看前端代

  • python使用paramiko模块实现ssh远程登陆上传文件并执行

    程序执行时需要读取两个文件command.txt和ipandpass.txt.格式如下: 复制代码 代码如下: command.txt:ThreadNum:1port:22local_dir:hello_mkdirremote_dir:hello_mkdiralter_auth:chmod 755 hello_mkdirexec_program:./hello_mkdir ipandpass.txt:ip username password 程序中的队列操作是修改的别的程序,写的确实不错.该程序

  • vue使用el-upload上传文件及Feign服务间传递文件的方法

    一.前端代码 <el-upload class="step_content" drag action="string" ref="upload" :multiple="false" :http-request="createAppVersion" :data="appVersion" :auto-upload="false" :limit="1&quo

  • 如何在vue3.0+中使用tinymce及实现多图上传文件上传公式编辑功能

    相关文档 本文部分内容借鉴: https://www.cnblogs.com/zhongchao666/p/11142537.html tinymce中文文档: http://tinymce.ax-z.cn/ 安装tinymce 1.安装相关依赖 yarn add tinymce || npm install tinymce -S yarn add @tinymce/tinymce-vue || npm install @tinymce/tinymce-vue -S 2.汉化编辑器前往此地址下载

  • 通过Ajax方式上传文件使用FormData进行Ajax请求

    通过传统的form表单提交的方式上传文件: Html代码  <form id= "uploadForm" action= "http://localhost:8080/cfJAX_RS/rest/file/upload" method= "post" enctype ="multipart/form-data"> <h1 >测试通过Rest接口上传文件 </h1> <p >指定文

  • 简述Java异步上传文件的三种方式

    本文为大家分享了三种Java异步上传文件方式,供大家参考,具体内容如下 用第三方控件,如Flash,ActiveX等浏览器插件上传. 使用隐藏的iframe模拟异步上传. 使用XMLHttpRequest2来实现异步上传. 第一种使用浏览器插件上传,需要一定的底层编码功底,在这里我就不讲了,以免误人子弟,提出这点大家可以自行百度. 第二种使用隐藏的iframe模拟异步上传.为什么在这里说的是模拟呢?因为我们其实是将返回结果放在了一个隐藏的iframe中,所以才没有使当前页面跳转,感觉就像是异步操

随机推荐