前言

  在某种情况下,后台服务可能需要访问另一台服务器的REST接口。以前估计不少人用的都是HttpRequest类来着,结合Paser解析JSON格式的Body。现在Spring Boot的Web Starter就自带了RestTemplate,直接用它的就好了。最好不要再往项目里导新的依赖。这里做了点整理,分享出来。发

简单的请求

一、GET请求

案例如下:

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<CustomClass> responseEntity = restTemplate.getForEntity(url, CustomClass.class);
CustomClass response = responseEntity.getBody();

(1)getForEntity 顾名思义就是发送GET请求,并得到一个对象

(2)这里的URL应该是完整的,即应该是这样的格式:"http://域名:端口/xxx/yyy"

(3)CustomClass是你自己定义的类,tempalte会将请求响应的JSON格式的body解析成CustomClass。

(4)ResponseEntity是请求响应的结果,可以获取响应码,以及最重要的响应Body

注意:由于RestTemplate是使用Jackson来进行映射的,而Jackson本质上是用setter/getter来实现的。其中JSON字符串转对象需要setter,对象转JSON字符串需要getter。这里是字符转对象,所以你定义的类必须有setter。

二、POST请求

案例如下:

...
restTemplate.postForEntity(url, ParamObject, Response.class);
...

基本操作同上,不过postForEntity的第二个参数是请求对象,底层会将其转为JSON字符存入请求Body中

传输form/data

一、普通的表单请求

//用MultiValueMap存储表单数据
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("param1","1232");
param.add("param2","12312");
//用HttpEntity进行包装
HttpEntity<MultiValueMap<String,Object>> httpEntity = new HttpEntity<>(param);
//发送请求
ResponseEntity<Response> responseEntity = restTemplate.postForEntity(url, httpEntity, Response.class);

这就相对于提交了一个普通的表单

二、带文件的表单请求

有时候我们需要把本地文件通过Post请求发送给另一个应用,可以这么做。而对方接收的时候就用@RequestParam("file") MultipartFile来接收。

MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
//FileSystemResource是一个包装类,好统一处理
param.add("file", new FileSystemResource(new File(filePath)));
...

(1)网页上通过表单上传文件,默认标识符就是"file"

(2)经过FileSystemResource包装后,RestTemplate会利用File对象的InputStream从磁盘中读入文件内容,并写入HTTP请求body中。

三、带文件的表单请求——文件从客户端而来(MultipartFile)

//file由客户端上传过来,直接转发,不经过磁盘
@PostMapping("/some-url")
public SomeResponse function(@RequestParam("file") MultipartFile file, ...) {
...
MultiValueMap<String, Object> param = new LinkedMultiValueMap();
param.add("file", new MultipartFileResource(file));
...
}

MultipartFileResource类似FileSystemResource

四、带文件的表单请求——本地没有文件,只有文件的文本内容

可能存在这种情况,即你本地保存的是文本文件的内容,(如保存在数据库中,用text存储。因为这样比较方便管理)而另一个服务器需要以文件的形式接收你的文本内容。即它会用一个MultipartFile来接收。这时候首先你从数据库中把文本内容读出来,传统数据库存储位置就在磁盘,这已经是不小的开销了,难道你还要把文本以文件的形式写到磁盘再传输吗?这种操作是非常愚蠢的。既然我们已经知道请求本质上传递的是字节数组,那何不就仿造FileSystemResource写一个适配类呢?

//该类与FileSystemResouce同父类
public class TextFeignFileResource extends AbstractResource {
//文本的字节信息
private byte[] bytes;
//当前读到的位置
private int index = 0;
//文件名
private String filename; //构造函数需要两个参数,一个是文件名,随便取
//另一个就是文本内容,String类型足够存文本的
public TextFeignECLFileResource(String filename, String content) {
this.filename = filename;
this.bytes = content.getBytes();
} @Override
public String getDescription() {
return null;
} @Override
public InputStream getInputStream() throws IOException {
return new InputStream() {
//注意这里的返回值int是一个八位的字节的数值表示
//并不是读取到的字节个数
@Override
public int read() throws IOException {
if (index >= bytes.length)
return -1; //返回-1是标准,表示读取结束
return bytes[index++];
}
};
} @Override
public boolean exists() {
return true;
} @Override
public boolean isFile() {
return true;
} @Override
public boolean isReadable() {
return true;
} @Override
public long contentLength() throws IOException {
return bytes.length;
} @Override
public String getFilename() {
return filename;
}
}

使用方式:

MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("file", new TextFeignFileResource("test.txt", "hello world"));

注意:这里之所以能这么做是因为普通的文本文件没有文件头等额外的描述信息

19-05-16补充

使用Jodd的Http API会更方便一点。

【API知识】RestTemplate的使用的更多相关文章

  1. Vue.js 2.x API 知识梳理(一) 全局配置

    Vue.js 2.x API 知识梳理(一) 全局配置 Vue.config是一个对象,包含Vue的全局配置.可以在启动应用之前修改指定属性. 这里不是指的@vue/cli的vue.config.js ...

  2. Selenium WebDriver Api 知识梳理

    之前一直没有系统的梳理WebDriver Api的相关知识,今天借此机会整理一下. 1.页面元素定位 1.1.8种常用定位方法 # id定位 driver.find_element_by_id() # ...

  3. 项目中的web api知识总结

    最近在做公司的项目,自己负责webapi的框架的搭建与开发,最近很忙,一直没时间对工作中遇到的知识点缺少个总结,现总结一下,对自己是个提升,如果个人的小点点小总结能对博友有帮助那也是善莫大焉. (1) ...

  4. MAC OS X API知识摘抄

    本文为信息为网上各个地方收集整理Carbon和Cocoa,Toolbox,POSIX,JAVA并列成为Mac OS X五个主要的API.与Cocoa相较之下,Carbon是非物件导向(Procedur ...

  5. 【API知识】类型转换工具ConvertUtils引发的思考

    前言 在读取Excel文件数据,有时候不可避免地需要把获取到的字符串转型为基本类型的对象.以前都是自己写转换,难度也不大.后来听说,有可以直接用的轮子——Apache 的commons-beanuti ...

  6. java API 知识:截取特殊标识之前的字符串

    一: double a = 23.36; String b = String.valueOf(a); String d = b.substring(, b.lastIndexOf(".&qu ...

  7. 【API知识】一种你可能没见过的Controller形式

    前言 这里分享一下我遇到的一个挺有意思的Controller形式,内容涉及@RequestMapping注解的原理. 实际案例 一.基本描述 项目甲中有多个模块,其中就有模块A和B.(这里的模块指的是 ...

  8. 【API知识】ElementUI一些问题的解决方案

    前言 本人并不是前端开发人员,不过前端的界面和交互也没少写.以下整理一下我在使用elementUI过程中遇到的问题和对应的解决方案. 正文 1.表格字段过长省略 elmentUI的table-colu ...

  9. 【API知识】MongoTemplate非映射方式操作Document

    前言 我是MongoDB小白,刚开始学.不过,我猜大多数使用MongoDB的,都是采用映射方式处理的,即需要有定义好的用于映射的实体类.但是这样的话,如果表的结构在未来可能频繁变动,增删字段,甚至添加 ...

随机推荐

  1. C语言的数据类型的本质和提高学习

    一.数据类型的概念 类型是对数据的抽象 类型是相同的数据有相同的表示形式.存储格式以及相关的操作 程序中使用的数据必定属于某一种数据类型 ​ 1.算术类型: 包括三种类型:整数类型.浮点类型,枚举型. ...

  2. web端代码提示

    web端代码提示 这个功能是基本完成了,但是与需求不一致.但是废弃挺可惜的,所以就单独拿出来作为一个例子记录一下. 其中还包括了,java代码的自动编译和执行,在web端显示执行结果. 下载链接: h ...

  3. 解决.Net Core跨域问题

    什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域 跨域的几种情况 1.端口和协议的不同,只能通过后台来解决 2.localhost和127.0.0.1虽然 ...

  4. 即时消息Toast和对话框

    public static Toast makeText(Context context, CharSequence text, int duration) protected void onDest ...

  5. Java的this关键字在继承时的作用

    1.this.属性 class A{ int a = 10; public void play(){ System.out.println(this.a); } } class B extends A ...

  6. ppt制作动态表格与文字

          在工作中经常与ppt打交道的小伙伴们,是不是非常想让自己做的ppt图表能够动起来,显得高大上一点呢?比如让柱形图慢慢长起来,让折线图慢慢画出来,让文字像字幕一样缓缓上升?本文将给大家整理几 ...

  7. _ZNote_Chrom_插件_Chrom运行Android软件_APK

    https://chrome.google.com/webstore/detail/arc-welder/emfinbmielocnlhgmfkkmkngdoccbadn?utm_source=chr ...

  8. IDEA教程

    IDE-Intellij IDEA 之前同事一直给我推荐IDEA,说跟eclipse相比就是石器时代的工具,我一直任何一个工具熟练起来都很牛逼,所以一直坚持使用eclipse,不过看了下IDEA的功能 ...

  9. Leetcode(一)两数之和

    1.两数之和 题目要求: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重 ...

  10. postgresql数据库查询慢SQL

    --查询总耗时最长SQLselect * from pg_stat_statements order by total_time desc;--查询平均耗时最长SQLselect * from pg_ ...