一文吃透接口调用神器RestTemplate

文末可以领取所有系列高清 pdf。

大家好,我是路人,这是 SpringMVC 系列第 21 篇。

本文介绍 Spring web 中特别牛逼的一个类 RestTemplate。

目录

  • 1、RestTemplate 概述

  • 2、案例代码

    • 2.1、git 地址

    • 2.2、关键代码位置

    • 2.3、如何运行测试用例?

  • 3、发送 Get 请求

    • 3.1、普通请求

    • 3.2、url 中含有动态参数

    • 3.3、接口返回值为泛型

    • 3.4、下载小文件

    • 3.5、下载大文件

    • 3.6、传递头

    • 3.7、综合案例:含头、url 动态参数

  • 4、POST 请求

    • 4.1、post 请求常见的 3 种类型

    • 4.2、普通表单请求

    • 4.3、上传本地文件

    • 4.4、通过流或字节数组的方式上传文件

    • 4.5、复杂表单:多个普通元素+多文件上传

    • 4.6、发送 json 格式数据:传递 java 对象

    • 4.7、发送 json 格式数据:传递 java 对象,返回值为泛型

    • 4.8、发送 json 字符串格式数据

  • 5、DELETE、PUT、OPTION 请求

    • 5.1、DELETE 请求

    • 5.2、PUT 请求

    • 5.3、OPTIONS 请求

  • 6、集成 HttpClient

  • 7、集成 okhttp

  • 8、总结

  • 9、SpringMVC 系列目录

  • 10、更多好文章

  • 11、【路人甲 Java】所有系列高清 PDF

1、RestTemplate 概述

发送 http 请求,估计很多人用过 httpclient 和 okhttp,确实挺好用的,而 Spring web 中的 RestTemplate 和这俩的功能类似,也是用来发送 http 请求的,不过用法上面比前面的 2 位要容易很多。

spring 框架提供的 RestTemplate 类可用于在应用中调用 rest 服务,它简化了与 http 服务的通信方式,统一了 RESTful 的标准,封装了 http 链接, 我们只需要传入 url 及返回值类型即可。相较于之前常用的 HttpClient,RestTemplate 是一种更优雅的调用 RESTful 服务的方式。

在 Spring 应用程序中访问第三方 REST 服务与使用 Spring RestTemplate 类有关。RestTemplate 类的设计原则与许多其他 Spring 模板类(例如 JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。

RestTemplate 默认依赖 JDK 提供 http 连接的能力(HttpURLConnection),如果有需要的话也可以通过 setRequestFactory 方法替换为例如 Apache HttpComponents、Netty 或 OkHttp 等其它 HTTP library。

考虑到 RestTemplate 类是为调用 REST 服务而设计的,因此它的主要方法与 REST 的基础紧密相连就不足为奇了,后者是 HTTP 协议的方法:HEAD、GET、POST、PUT、DELETE 和 OPTIONS。例如,RestTemplate 类具有 headForHeaders()、getForObject()、postForObject()、put()和 delete()等方法。

下面给大家上案例,案例是重点,通过案例,把我知道的用法都给盘出来。

2、案例代码

2.1、git 地址

https://gitee.com/javacode2018/springmvc-series

10d8584b55c22fe2e509a0a93fc0126a.png

2.2、关键代码位置

文中的所有 controller 代码,在RestTemplateTestController类中。

所有@Test 用例的代码,在RestTemplateTest

3c0bd3eaa63e802b41c52ec909fae3a5.png

2.3、如何运行测试用例?

  • 拉取项目

  • 将 chat16-RestTemplate 模块发布到 tomcat9 中

  • 运行 RestTemplateTest 中对应的用例即可

下面咱们来看 RestTemplate 常见的用法汇总。

3、发送 Get 请求

3.1、普通请求

接口代码

@GetMapping("/test/get")
@ResponseBody
public?BookDto?get()?{
????return?new?BookDto(1,?"SpringMVC系列");
}

使用 RestTemplate 调用上面这个接口,通常有 2 种写法,如下

@Test
public?void?test1()?{
????RestTemplate?restTemplate?=?new?RestTemplate();
????String?url?=?"http://localhost:8080/chat16/test/get";
????//getForObject方法,获取响应体,将其转换为第二个参数指定的类型
????BookDto?bookDto?=?restTemplate.getForObject(url,?BookDto.class);
????System.out.println(bookDto);
}

@Test
public?void?test2()?{
????RestTemplate?restTemplate?=?new?RestTemplate();
????String?url?=?"http://localhost:8080/chat16/test/get";
????//getForEntity方法,返回值为ResponseEntity类型
????//?ResponseEntity中包含了响应结果中的所有信息,比如头、状态、body
????ResponseEntity<BookDto>?responseEntity?=?restTemplate.getForEntity(url,?BookDto.class);
????//状态码
????System.out.println(responseEntity.getStatusCode());
????//获取头
????System.out.println("头:"?+?responseEntity.getHeaders());
????//获取body
????BookDto?bookDto?=?responseEntity.getBody();
????System.out.println(bookDto);
}

test1 输出

BookDto{id=1,?name='SpringMVC系列'}

test2 输出

200?OK
头:[Content-Type:"application/json;charset=UTF-8",?Transfer-Encoding:"chunked",?Date:"Sat,?02?Oct?2021?07:05:15?GMT",?Keep-Alive:"timeout=20",?Connection:"keep-alive"]
BookDto{id=1,?name='SpringMVC系列'}

3.2、url 中含有动态参数

接口代码

@GetMapping("/test/get/{id}/{name}")
@ResponseBody
public?BookDto?get(@PathVariable("id")?Integer?id,?@PathVariable("name")?String?name)?{
????return?new?BookDto(id,?name);
}

使用 RestTemplate 调用上面这个接口,通常有 2 种写法,如下

@Test
public?void?test3()?{
????RestTemplate?restTemplate?=?new?RestTemplate();
????//url中有动态参数
????String?url?=?"http://localhost:8080/chat16/test/get/{id}/{name}";
????Map<String,?String>?uriVariables?=?new?HashMap<>();
????uriVariables.put("id",?"1");
????uriVariables.put("name",?"SpringMVC系列");
????//使用getForObject或者getForEntity方法
????BookDto?bookDto?=?restTemplate.getForObject(url,?BookDto.class,?uriVariables);
????System.out.println(bookDto);
}

@Test
public?void?test4()?{
????RestTemplate?restTemplate?=?new?RestTemplate();
????//url中有动态参数
????String?url?=?"http://localhost:8080/chat16/test/get/{id}/{name}";
????Map<String,?String>?uriVariables?=?new?HashMap<>();
????uriVariables.put("id",?"1");
????uriVariables.put("name",?"SpringMVC系列");
????//getForEntity方法
????ResponseEntity<BookDto>?responseEntity?=?restTemplate.getForEntity(url,?BookDto.class,?uriVariables);
????BookDto?bookDto?=?responseEntity.getBody();
????System.out.println(bookDto);
}

test3 输出

BookDto{id=1,?name='SpringMVC系列'}

test4 输出

BookDto{id=1,?name='SpringMVC系列'}

3.3、接口返回值为泛型

接口代码

@GetMapping("/test/getList")
@ResponseBody
public?List<BookDto>?getList()?{
????return?Arrays.asList(
????????????new?BookDto(1,?"Spring高手系列"),
????????????new?BookDto(2,?"SpringMVC系列")
????);
}

当接口的返回值为泛型的时候,这种情况比较特殊,使用 RestTemplate 调用上面这个接口,代码如下,需要用到restTemplate.exchange的方法,这个方法中有个参数是ParameterizedTypeReference类型,通过这个参数类指定泛型类型

@Test
public?void?test5()?{
????RestTemplate?restTemplate?=?new?RestTemplate();
????//返回值为泛型
????String?url?=?"http://localhost:8080/chat16/test/getList";
????//若返回结果是泛型类型的,需要使用到exchange方法,
????//这个方法中有个参数是ParameterizedTypeReference类型,通过这个参数类指定泛型类型
????ResponseEntity<List<BookDto>>?responseEntity?=
????????????restTemplate.exchange(url,
????????????????????HttpMethod.GET,
????????????????????null,
????????????????????new?ParameterizedTypeReference<List<BookDto>>()?{
????????????????????});
????List<BookDto>?bookDtoList?=?responseEntity.getBody();
????System.out.println(bookDtoList);
}

输出

[BookDto{id=1,?name='Spring高手系列'},?BookDto{id=2,?name='Sprin
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值