RestTemplate使用

1、引文

之前做需求的时候,有一次遇到一个场景:判断某一天是工作日、休息日或节假日。从网上找了一个接口http://tool.bitefu.net/jiari/ 用法如下图

image
image
image

如上所示,我们仅在这个接口尾部输入yyyyMMDD格式的日期参数,就能知道当天是工作日(0)、休息日(1)和节假日(2)了。

做法如下:

public static String httpClient(String dateString){
        //创建客户端
       CloseableHttpClient httpClient = HttpClients.createDefault();
       //拼接uri
       String uri = "http://tool.bitefu.net/jiari/?d=%s";
       String format = String.format(uri, dateString);
       //创建请求
       HttpGet httpGet = new HttpGet(format);
       try {
          //调用接口,返回结果
           CloseableHttpResponse response = httpClient.execute(httpGet);
           if (response!=null){
               HttpEntity entity = response.getEntity();
               String result = EntityUtils.toString(entity,"UTF-8");
               return result;
           }else{
               return "error";
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
       return "error";
   }

可以发现当前代码中其实只有极少的代码与调用接口有关,我们希望仅仅需要传入uri和参数,就能够返回我们想要的结果。在这里我们不得不捕获或抛出检查型异常IOException。如果我们在编写一个方法,调用其他接口,又需要我们写非常多的重复的代码。这并不符合我的期望。

Spring 提供给我们一些模版,给我们的很大的便利。举个例子,我们在使用传统的jdbc去操作数据库的时候,我们需要加载驱动、建立连接、写sql、传参、执行和返回结果,在完成之后我们还需要去关闭链接,不得不去捕获抛出的检查型异常。但是spring提供给我们的jdbcTempalte,在设置了dataSource之后,我们仅仅需要执行类似这样一句

jdbcTemplate.setDataSource(dataSource);
String sql = "select count(*)  from user";
Long num = (long) jdbcTemplate.queryForObject(sql, Long.class);

即可返回user的数量,它已经帮我们完成连接的建立、关闭以及异常处理等等操作。

RestTemplate也是这样为了提供给我们方便的而生的,它定义了36个与REST资源交互的方法,其中的大多数都对应于HTTP的方法。但是,没有足够的篇幅涵盖所有的36个方法。其实,这里面只有11个独立的方法,其中有十个有三种重载形式,而第十一个则重载了六次,这样一共形成了36个方法。

除了TRACE以外,RestTemplate涵盖了所有的HTTP动作。除此之外,execute()和exchange()提供了较低层次的通用方法来使用任意的HTTP方法。

image

2、Get

image

从上面的三个方法中进行分析:
第一个方法传参是直接调用url,responseType代表了返回值的类型。
第二个方法提供了多个参数的植入,通常来说,这些参数是根据url中填参部分,依次填入。
第三个方法利用Map填参,Map的key值与url缺少的参数名要保持一致。

image

上图展示了三种方法的使用方式,它们均可以给出我们想要的结果。

此外还有一个方法getForEntity( ),它的使用方式和getForObject( )大同小异,它们都执行根据URL检索资源的GET请求。它们都将资源根据responseType参数匹配为一定的类型。唯一的区别在于getForObject()只返回所请求类型的对象,而getForEntity()方法会返回请求的对象以及响应相关的额外信息。如下所示,它还能返回http状态码以及的响应头信息。

image

为了实现更通用的HTTP头信息访问,HttpHeaders提供了get()方法和getFirst()方法。两个方法都接受String参数来标识所需要的头信息。get()将会返回一个String值的列表,其中的每个值都是赋给该头部信息的,而getFirst()方法只会返回第一个头信息的值。

3、POST

image

不管是URL类型还是String类型,第一个参数都是资源要POST到的URL;
第二个参数是要发送的对象;
第三个参数是预期返回的Java类型。
在将URL作为String类型的两个版本中,第四个参数指定了URL变量(要么是可变参数列表,要么是一个Map,与上一节的使用方法一致)。

postForLocation 、postForObject 、postForEntity的区别

类似于get类型,postForObject 和postForEntity拥有的作用类似,他们讲第二个参数要发送的对象推送到服务器进行处理。而postForEntity的场景还是为了查看一些响应中的头信息,比如说一些Location信息,我们可以使用ResponseEntity.getHeaders().getLocation()的方式获得。如果要同时接收所发送的资源和响应头,postForEntity()方法是很便利的。但通常你并不需要将资源发送回来(毕竟,将其发送到服务器端是第一位的)。如果你需要的仅仅是Location头信息的值,那么使用RestTemplate的postForLocation()方法会更简单。

4、Delete

image

实际上,delete是RestTemlate中最简单的方法,唯一需要我们提供的就是url和要删除的对象的ID即可,在这里就不举例了。

5、Put

image

在RestFul接口规范中,我们通常使用put来进行数据的更新修改。

RestTemplate提供了三个简单的put()方法,第一个参数是指定的Url,第二个参数是需要更新的对象,后面的参数是对utl的补全。

从getForObject()和getForEntity()方法中我们也看到了,使用基于String的其他put()方法能够为我们减少创建URI的不便。对象将被转换成什么样的内容类型很大程度上取决于传递给put()的类型。如果给一个String值,那么将会使用StringHttpMessageConverter:这个值直接被写到请求体中,内容类型设置为“text/plain”。如果给定一个MultiValueMap<String,String>,那么这个Map中的值将会被FormHttpMessageConverter以“application/x-www-form-urlencoded”的格式写到请求体中。

6、exchange

image

RestTempalte中定义很多重载的exchange()方法,如下
String|URL :请求路径
HttpMethod:Http的动作,如Get、delete等
requestEntity():在请求中发送资源,get可以为null
responseType(如果要获取状态码和header可使用ResponseEntity<T>):返回数据的类型
Map/Object... :填充Url的参数

exchange()利用HttpMethod这个参数,可以完成其他RestTemplate方法的工作,如上GET、POST、DELETE、PUT等。exchange()优于其他方法的点事它可以在发送给服务器的请求中加入头信息。


MultiValueMap<String,String> headers = new LinkedMultiValueMap<>();

headers.add("User-Agent","Java/1.8.0_161");

...

HttpEntity<Object> requestEntity = new HttpEntity<>(headers);

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容