记录:288
场景:基于Spring Boot应用RestTemplate调用http请求。使用RestTemplate调用服务端发布的POST、GET、HEAD、PUT、PATCH、DELETE、OPTIONS请求,以及对TRACE请求的验证。使用RestTemplate提供的不同方法调用服务端发布的POST、GET请求。
版本:
Spring Boot 2.6.3
Spring Framework 5.3.15
Spring Cloud 2021.0.1
一、基础
本例应用RestTemplate调用http请求是基于HTTP协议。
1.名词
名词内容取自网络,聚合而成。
1.1 HTTP协议
(1)超文本传输协议,即HyperText Transfer Protocol。
(2)用于从服务器传输超文本到本地浏览器的传送协议。
(3)基于TCP/IP通信协议来传递数据。
(4)HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。
1.2 HTTPS协议
(1)超文本传输安全协议,即HyperText Transfer Protocol Secure。
(2)一种通过计算机网络进行安全通信的传输协议。
(3)HTTPS 经由 HTTP 进行通信,利用 SSL/TLS 来加密数据包,主要目的是提供对网站服务器的身份认证,保护交换资料的隐私与完整性。
1.3 TCP/IP协议
(1)传输控制协议/网际协议即Transmission Control Protocol/Internet Protocol。
(2)计算机必须遵守的规则的描述,只有遵守这些规则,计算机之间才能进行通信。
(3)TCP/IP四层模型:网络接口层、网络层、传输层、应用层。
1.4 OSI参考模型(OSI七层模型)
(1)Open System Interconnection,即OSI参考模型。
(2)国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系。
(3)物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
1.5 SSL/TLS协议
(1)SSL,安全套接字层,即Secure Sockets Layer。
(2)TLS,安全传输层安全,即Transport Layer Security。
(3)用于保障通信数据传输安全,利用数据加密技术,可确保数据在网络上传输过程中不会被截取。用于在两个通信应用程序之间提供保密性和数据完整性。
1.6 URI和URL
(1)URI: 统一资源标识符,即Uniform Resource Identifier。是一个用于标识某一互联网资源名称的字符串。
(2)URL: 统一资源定位系统,即Uniform Resource Locator。是因特网的万维网服务程序上用于指定信息位置的表示方法。是WWW的统一资源定位标志,就是指网络地址。
(3)URL是一种URI,它标识一个互联网资源,并指定对其进行操作或获取该资源的方法。
2.HTTP报文格式
2.1 客户端请求消息格式
客户端请求消息格式:
请求行、请求头部、空行和请求数据
2.2 服务端响应消息格式
服务端响应消息格式:
状态行、响应头部、空行和响应正文
3.GET请求和POST请求报文
使用报文截取工具截取报文,可以直观感受报文格式。本例使用Postman工具发起请求。
3.1 GET请求报文
请求URL:
http://127.0.0.1:19091/server/comm/f3/HangZhou20220721
(1)客户端请求报文
(2)服务端响应报文
3.2 POST请求报文
请求URL:
http://127.0.0.1:19091/server/comm/f1
入参:
{
"userName":"HangZhou20220721",
"tradeName":"Vue进阶教程"
}
(1)客户端请求报文
(2)服务端响应报文
4.Spring对http请求报文封装对应的类
本例只给出类名和类的属性,不给出方法。
4.1 HttpHeaders
HttpHeaders,即org.springframework.http.HttpHeaders。
HttpHeaders,实现MultiValueMap接口,org.springframework.util.MultiValueMap。
MultiValueMap接口,继承java.util.Map接口。
从以上可以确定,HttpHeaders存储请求头数据以Key,Value键值对为基础型式。
HttpHeaders定义属性
(1)以public static final修饰的属性有62个,基本上涵盖对请求头常用属性设置。以下列出部分。
public static final String ACCEPT = "Accept";
public static final String ACCEPT_CHARSET = "Accept-Charset";
public static final String ACCEPT_ENCODING = "Accept-Encoding";
public static final String ACCEPT_LANGUAGE = "Accept-Language";
......
public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
public static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
public static final String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
public static final String ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age";
public static final String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
public static final String ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method";
......
public static final String AUTHORIZATION = "Authorization";
......
public static final String CONTENT_TYPE = "Content-Type";
.......
final MultiValueMap<String, String> headers;
(2)定义final MultiValueMap<String, String> headers;提供给客户端设置。提供了set和add方法去设置请求头,例如:
//直接add或者set到headers属性中
public void add(String headerName, @Nullable String headerValue) {
this.headers.add(headerName, headerValue);
}
public void addAll(String key, List<? extends String> values) {
this.headers.addAll(key, values);
}
public void addAll(MultiValueMap<String, String> values) {
this.headers.addAll(values);
}
public void set(String headerName, @Nullable String headerValue) {
this.headers.set(headerName, headerValue);
}
public void setAll(Map<String, String> values) {
this.headers.setAll(values);
}
//直接设置属性,最终也会写入headers
public void setCacheControl(@Nullable String cacheControl) {
this.setOrRemove("Cache-Control", cacheControl);
}
4.2 HttpEntity
HttpEntity,即org.springframework.http.HttpEntity。
请求头(响应头):HttpHeaders,即org.springframework.http.HttpHeaders。
请求体(响应体):T body,T匹配传入的对象类型。
只提供HttpEntity的属性,不提供方法,细节移步源码。
public class HttpEntity<T> {
private final HttpHeaders headers;
@Nullable
private final T body;
}
4.3 RequestEntity
RequestEntity,即org.springframework.http.RequestEntity。
RequestEntity继承HttpEntity。
只提供RequestEntity的属性,不提供方法,细节移步源码。
public class RequestEntity<T> extends HttpEntity<T> {
@Nullable
private final HttpMethod method;
@Nullable
private final URI url;
@Nullable
private final Type type;
}
由于RequestEntity继承HttpEntity,把属性都写到一起,就直观的体现了请求消息报文格式。
public class RequestEntity<T> {
@Nullable
private final HttpMethod method;
@Nullable
private final URI url;
@Nullable
private final Type type;
private final HttpHeaders headers;
@Nullable
private final T body;
}
4.4 ResponseEntity
ResponseEntity,即org.springframework.http.ResponseEntity。
ResponseEntity继承HttpEntity。
只提供ResponseEntity的属性,不提供方法,细节移步源码。
public class ResponseEntity<T> extends HttpEntity<T> {
private final Object status;
}
由于ResponseEntity继承HttpEntity,把属性都写到一起,就直观的体现了响应消息报文格式。
public class ResponseEntity<T>{
private final Object status;
private final HttpHeaders headers;
@Nullable
private final T body;
}
5.几个关于http请求常用常量类
几个关于http请求常用常量类
HttpMethod,即org.springframework.http.HttpMethod,提供8个请求方法枚举。
HttpStatus,即org.springframework.http.HttpStatus,提供68个已经定义好状态,比如200代表OK;405代表Method Not Allowed。
MediaType,即org.springframework.http.MediaType,列举了http传输媒体类型,比如application/json等。
二、RestTemplate支持的7种请求和TRACE请求
在Spring的HttpMethod中提供了8中方法如下:
POST,GET,HEAD,PUT,PATCH,DELETE,OPTIONS,TRACE
但是,RestTemplate使用HttpMethod.TRACE时,抛出客户端异常错误,应该是不支持。
归来总结:
POST、PUT、PATCH、TRACE,归为一类,入参都需要传入请求体。
GET、HEAD、DELETE、OPTIONS,归为一类,入参不需要传入请求体。
1.POST请求服务端与客户端
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest2")
public class Restful2Controller {
/**
* 1.处理POST请求
*/
@PostMapping("/f1")
public Object f1(@RequestBody Object obj) {
log.info("Restful2Controller->f1,接收参数,obj = " + obj.toString());
log.info("Restful2Controller->f1,处理业务.");
log.info("Restful2Controller->f1,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils8Method {
public static void main(String[] args) throws Exception {
f1();
}
/**
* 1.POST请求客户端
*/
public static void f1() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest2/f1";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<String> entity = new HttpEntity<>(json, headers);
// 5.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.postForObject(postUrl, entity, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
2.GET请求服务端与客户端
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest2")
public class Restful2Controller {
/**
* 2.处理GET请求
*/
@GetMapping("/f2")
public Object f2(@RequestParam("obj") String obj) {
log.info("Restful2Controller->f2,接收参数,obj = " + obj.toString());
log.info("Restful2Controller->f2,处理业务.");
log.info("Restful2Controller->f2,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils8Method {
public static void main(String[] args) throws Exception {
f2();
}
/**
* 2.GET请求客户端
*/
public static void f2() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest2/f2";
String obj = "Vue进阶教程";
String para = "?obj=" + obj;
getUrl = getUrl + para;
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.getForObject(getUrl, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
3.HEAD请求服务端与客户端
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest2")
public class Restful2Controller {
/**
* 3.处理HEAD请求
*/
@RequestMapping(value = "/f3", method = RequestMethod.HEAD)
public Object f3(@RequestParam("obj") String obj) {
log.info("Restful2Controller->f3,接收参数,obj = " + obj.toString());
log.info("Restful2Controller->f3,处理业务.");
log.info("Restful2Controller->f3,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils8Method {
public static void main(String[] args) throws Exception {
f3();
}
/**
* 3.HEAD请求客户端
*/
public static void f3() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest2/f3";
String obj = "Vue进阶教程";
String para = "?obj=" + obj;
getUrl = getUrl + para;
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
HttpHeaders resultData = restTemplate.headForHeaders(getUrl);
System.out.println("从服务端返回结果: " + resultData);
}
}
4.PUT请求服务端与客户端
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest2")
public class Restful2Controller {
/**
* 4.处理PUT请求
*/
@PutMapping("/f4")
public Object f4(@RequestBody Object obj) {
log.info("Restful2Controller->f4,接收参数,obj = " + obj.toString());
log.info("Restful2Controller->f4,处理业务.");
log.info("Restful2Controller->f4,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils8Method {
public static void main(String[] args) throws Exception {
f4();
}
/**
* 4.PUT请求客户端
*/
public static void f4() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest2/f4";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<String> entity = new HttpEntity<>(json, headers);
// 5.使用RestTemplate发起请求与接收返回值
restTemplate.put(postUrl, entity);
System.out.println("从服务端返回结果: put请求返回类型为void");
}
}
5.PATCH请求服务端与客户端
注意:处理PATCH请求时,在创建RestTemplate时,需要注入ClientHttpRequestFactory实现类HttpComponentsClientHttpRequestFactory。因为默认实现类SimpleClientHttpRequestFactory不支持PATCH方法。
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest2")
public class Restful2Controller {
/**
* 5.处理PATCH请求
*/
@PatchMapping("/f5")
public Object f5(@RequestBody Object obj) {
log.info("Restful2Controller->f5,接收参数,obj = " + obj.toString());
log.info("Restful2Controller->f5,处理业务.");
log.info("Restful2Controller->f5,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils8Method {
public static void main(String[] args) throws Exception {
f5();
}
/**
* 5.PATCH请求客户端
*/
public static void f5() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest2/f5";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(1000 * 6);
requestFactory.setReadTimeout(1000 * 6);
RestTemplate restTemplate = new RestTemplate(requestFactory);
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<String> entity = new HttpEntity<>(json, headers);
// 5.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.patchForObject(postUrl, entity, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
6.DELETE请求服务端与客户端
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest2")
public class Restful2Controller {
/**
* 6.处理DELETE请求
*/
@DeleteMapping("/f6")
public Object f6(@RequestParam("obj") String obj) {
log.info("Restful2Controller->f6,接收参数,obj = " + obj.toString());
log.info("Restful2Controller->f6,处理业务.");
log.info("Restful2Controller->f6,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils8Method {
public static void main(String[] args) throws Exception {
f6();
}
/**
* 6.DELETE请求客户端
*/
public static void f6() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest2/f6";
String obj = "Vue进阶教程";
String para = "?obj=" + obj;
getUrl = getUrl + para;
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
restTemplate.delete(getUrl);
System.out.println("从服务端返回结果: delete请求返回类型为void");
}
}
7.OPTIONS请求服务端与客户端
注意,在调用OPTIONS时,服务端注入HttpServletResponse,为了设置响应头信息,只有设置了响应头,OPTIONS的客户端才能获取到具体值。
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest2")
public class Restful2Controller {
@Autowired
private HttpServletResponse response;
/**
* 7.处理OPTIONS请求
*/
@RequestMapping(value = "/f7", method = RequestMethod.OPTIONS)
public Object f7(@RequestParam("obj") String obj) {
log.info("Restful2Controller->f7,接收参数,obj = " + obj.toString());
log.info("Restful2Controller->f7,处理业务.");
log.info("Restful2Controller->f7,返回.");
response.setHeader("Allow","POST,GET");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils8Method {
public static void main(String[] args) throws Exception {
f7();
}
/**
* 7.OPTIONS请求客户端
*/
public static void f7() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest2/f7";
String obj = "Vue进阶教程";
String para = "?obj=" + obj;
getUrl = getUrl + para;
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
Set<HttpMethod> resultData = restTemplate.optionsForAllow(getUrl);
System.out.println("从服务端返回结果: " + resultData);
}
}
8.TRACE请求服务端与客户端
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest2")
public class Restful2Controller {
/**
* 8.处理TRACE请求
*/
@RequestMapping(value = "/f8", method = RequestMethod.TRACE)
public Object f8(@RequestBody Object obj) {
log.info("Restful2Controller->f8,接收参数,obj = " + obj.toString());
log.info("Restful2Controller->f8,处理业务.");
log.info("Restful2Controller->f8,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils8Method {
public static void main(String[] args) throws Exception {
f8();
}
/**
* 8.TRACE请求客户端
* 注意:
* RestTemplate使用HttpMethod.TRACE时,
* 抛出客户端异常错误,应该是不支持
*/
public static void f8() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest2/f8";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
List<HttpMethod> allowedMethods = new ArrayList<>();
allowedMethods.add(HttpMethod.TRACE);
headers.setAccessControlAllowMethods(allowedMethods);
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<String> entity = new HttpEntity<>(json, headers);
// 5.使用RestTemplate发起请求与接收返回值
ResponseEntity<String> resultData = restTemplate.exchange(postUrl,
HttpMethod.TRACE, entity, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
三、POST请求和GET请求
针对POST请求和GET请求这两个常用请求,RestTemplate支持的各种场景给出示例。
1.POST请求
1.1 POST请求方式1(postForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 1.处理POST请求
* 入参使用@RequestBody封装为对象
*/
@PostMapping("/f1")
public Object f1(@RequestBody Object obj) {
log.info("RestfulController->f1,接收参数,obj = " + obj.toString());
log.info("RestfulController->f1,处理业务.");
log.info("RestfulController->f1,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f1();
}
/**
* 1.POST请求客户端
* 服务端入参: 使用@RequestBody注解
* 服务端返回值: 使用@ResponseBody注解的JavaBean对象
* 客户端方法: postForObject
* 客户端入参:
* 使用HttpEntity封装,
* 请求头(headers): HttpHeaders
* 请求体(body): String类型的JSON字符串
* 客户端返回值: String类型
*/
public static void f1() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest/f1";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<String> entity = new HttpEntity<>(json, headers);
// 5.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.postForObject(postUrl, entity, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
1.2 POST请求方式2(postForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 1.1处理POST请求
* 入参为字符串
*/
@PostMapping("/f1_1")
public Object f1_1(String obj) {
log.info("RestfulController->f1_1,接收参数,obj = " + obj.toString());
log.info("RestfulController->f1_1,处理业务.");
log.info("RestfulController->f1_1,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f1_1();
}
/**
* 1.1 POST请求客户端
* 服务端入参: 不使用@RequestBody注解
* 服务端返回值: 使用@ResponseBody注解的JavaBean对象
* 客户端方法: postForObject
* 客户端入参:
* URL中使用占位符传参,String类型的JSON字符串
* 客户端返回值: String类型
*/
public static void f1_1() throws Exception {
// 1.请求URL,带占位符
String postUrl = "http://127.0.0.1:19091/server/rest/f1_1?&obj={json}";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 5.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.postForObject(postUrl, null, String.class, json);
System.out.println("从服务端返回结果: " + resultData);
}
}
1.3 POST请求方式3(postForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 1.2处理POST请求
* 入参obj01使用@RequestBody封装为对象
* 入参obj02字符串
*/
@PostMapping("/f1_2")
public Object f1_2(@RequestBody Object obj01, String obj02) {
log.info("RestfulController->f1_2,接收参数,obj01 = " + obj01.toString());
log.info("RestfulController->f1_2,接收参数,obj02 = " + obj02.toString());
log.info("RestfulController->f1_2,处理业务.");
log.info("RestfulController->f1_2,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f1_2();
}
/**
* 1.2 POST请求客户端
* 服务端入参:
* obj01使用@RequestBody注解封装,
* obj02只传递JSON字符串,不能使用@RequestBody注解,
* 服务端返回值: 使用@ResponseBody注解的JavaBean对象
* 客户端方法: postForObject
* 客户端入参:
* obj01:
* 使用HttpEntity封装,
* 请求头(headers): HttpHeaders
* 请求体(body): String类型的JSON字符串
* obj02:
* URL中使用占位符传参,String类型的JSON字符串
* 客户端返回值: String类型
*/
public static void f1_2() throws Exception {
// 1.请求URL,带占位符
String postUrl = "http://127.0.0.1:19091/server/rest/f1_2?&obj02={json}";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<String> entity = new HttpEntity<>(json, headers);
// 5.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.postForObject(postUrl, entity, String.class, json);
System.out.println("从服务端返回结果: " + resultData);
}
}
1.4 POST请求方式4(postForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 1.3处理POST请求
* 入参obj01字符串
* 入参obj02字符串
*/
@PostMapping("/f1_3")
public Object f1_3(String obj01, String obj02) {
log.info("RestfulController->f1_3,接收参数,obj01 = " + obj01.toString());
log.info("RestfulController->f1_3,接收参数,obj02 = " + obj02.toString());
log.info("RestfulController->f1_3,处理业务.");
log.info("RestfulController->f1_3,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f1_3();
}
/**
* 1.3 POST请求客户端
* 服务端入参:
* obj01只传字符串,不能使用@RequestBody注解
* obj02只传字符串,不能使用@RequestBody注解
* 服务端返回值: 使用@ResponseBody注解的JavaBean对象
* 客户端方法: postForObject
* 客户端入参:
* URL中使用占位符传参,使用Map传参
* 客户端返回值: String类型
*/
public static void f1_3() throws Exception {
// 1.请求URL,带占位符
String postUrl = "http://127.0.0.1:19091/server/rest/f1_3?&obj01={obj01Data}&obj02={obj02Data}";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
Map<String, String> para = new HashMap<>();
para.put("obj01Data", json);
para.put("obj02Data", "杭州,一个非常不错的城市.");
// 5.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.postForObject(postUrl, null, String.class, para);
System.out.println("从服务端返回结果: " + resultData);
}
}
1.5 POST请求方式5(postForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 1.处理POST请求
* 入参使用@RequestBody封装为对象
*/
@PostMapping("/f1")
public Object f1(@RequestBody Object obj) {
log.info("RestfulController->f1,接收参数,obj = " + obj.toString());
log.info("RestfulController->f1,处理业务.");
log.info("RestfulController->f1,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f1_4();
}
/**
* 1.4 POST请求客户端
* 服务端入参: 使用@RequestBody注解
* 服务端返回值: 使用@ResponseBody注解的JavaBean对象
* 客户端方法: postForObject
* 客户端入参:
* 使用HttpEntity封装,
* 请求头(headers): HttpHeaders
* 请求体(body): String类型的JSON字符串
* 使用URI封装URL参数
* 客户端返回值: String类型
*/
public static void f1_4() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest/f1";
URI uri = new URI(postUrl);
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<String> entity = new HttpEntity<>(json, headers);
// 5.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.postForObject(uri, entity, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
1.6 POST请求方式6(postForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 1.处理POST请求
* 入参使用@RequestBody封装为对象
*/
@PostMapping("/f1")
public Object f1(@RequestBody Object obj) {
log.info("RestfulController->f1,接收参数,obj = " + obj.toString());
log.info("RestfulController->f1,处理业务.");
log.info("RestfulController->f1,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f1();
}
/**
* 1.6 POST请求客户端
* 服务端入参: 使用@RequestBody注解
* 服务端返回值: 使用@ResponseBody注解的JavaBean对象
* 客户端方法: postForObject
* 客户端入参:
* 使用HttpEntity封装,
* 请求头(headers): HttpHeaders
* 请求体(body): String类型的JSON字符串
* 客户端返回值: 自定义对象ResultObj.class
*/
public static void f1_6() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest/f1";
// 2.请求参数JSON格式
UserModel userModel = new UserModel();
userModel.setUserName("HangZhou20220718");
userModel.setTradeName("Vue进阶教程");
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<UserModel> entity = new HttpEntity<>(userModel, headers);
// 5.使用RestTemplate发起请求与接收返回值
ResultObj resultData = restTemplate.postForObject(postUrl, entity, ResultObj.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
1.7 POST请求方式7(postForLocation)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 1.2处理POST请求
* 入参使用@RequestBody封装为对象
* 需注入HttpServletResponse和设置响应头
*/
@PostMapping("/f1_uri")
public Object f1_uri(@RequestBody Object obj) throws URISyntaxException {
log.info("CommonController->f1_uri,接收参数,obj = " + obj.toString());
log.info("CommonController->f1_uri,处理业务.");
log.info("CommonController->f1_uri,返回.");
// postForLocation返回值,不为空的话,必须设置响应头的Location属性
response.setHeader("Location", "/server/work");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f1_uri();
}
/**
* POST请求客户端
* 服务端入参: 使用@RequestBody注解
* 服务端返回值: 使用@ResponseBody注解的JavaBean对象
* 客户端方法: postForLocation
* 客户端入参:
* 使用HttpEntity封装,
* 请求头(headers): HttpHeaders
* 请求体(body): String类型的JSON字符串
* 客户端返回值: URI对象
*/
public static void f1_uri() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest/f1_uri";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<String> entity = new HttpEntity<>(json, headers);
// 5.使用RestTemplate发起请求与接收返回值
URI resultData = restTemplate.postForLocation(postUrl, entity);
System.out.println("从服务端返回结果: " + resultData);
}
}
1.8 POST请求方式8(postForEntity)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 1.处理POST请求
* 入参使用@RequestBody封装为对象
*/
@PostMapping("/f1")
public Object f1(@RequestBody Object obj) {
log.info("RestfulController->f1,接收参数,obj = " + obj.toString());
log.info("RestfulController->f1,处理业务.");
log.info("RestfulController->f1,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f1();
}
/**
* 1.5 POST请求客户端
* 服务端入参: 使用@RequestBody注解
* 服务端返回值: 使用@ResponseBody注解的JavaBean对象
* 客户端方法: postForEntity
* 客户端入参:
* 使用HttpEntity封装,
* 请求头(headers): HttpHeaders
* 请求体(body): String类型的JSON字符串
* 客户端返回值: ResponseEntity
* 功能: 便于获取HttpEntity的HttpHeaders信息
*/
public static void f1_5() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest/f1";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
HttpEntity<String> entity = new HttpEntity<>(json, headers);
// 5.使用RestTemplate发起请求与接收返回值
ResponseEntity<String> resultData = restTemplate.postForEntity(postUrl, entity, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
1.9 POST请求方式9(exchange)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 1.处理POST请求
* 入参使用@RequestBody封装为对象
*/
@PostMapping("/f1")
public Object f1(@RequestBody Object obj) {
log.info("RestfulController->f1,接收参数,obj = " + obj.toString());
log.info("RestfulController->f1,处理业务.");
log.info("RestfulController->f1,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f1();
}
/**
* 1.7 POST请求客户端
* 服务端入参: 使用@RequestBody注解
* 服务端返回值: 使用@ResponseBody注解的JavaBean对象
* 客户端方法: exchange
* 客户端入参:
* 使用RequestEntity封装HttpEntity等等
* 客户端返回值: ResponseEntity
*/
public static void f1_7() throws Exception {
// 1.请求URL
String postUrl = "http://127.0.0.1:19091/server/rest/f1";
// 2.请求参数JSON格式
Map<String, String> map = new HashMap<>();
map.put("userName", "HangZhou20220718");
map.put("tradeName", "Vue进阶教程");
String json = JSON.toJSONString(map);
// 3.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 4.设置RestTemplate参数(请求头和body)
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(mediaType);
headers.add("Accept", "application/json");
URI uri = new URI(postUrl);
RequestEntity<String> requestEntity = new RequestEntity<>(json, headers, HttpMethod.POST, uri);
// 5.使用RestTemplate发起请求与接收返回值
ResponseEntity<String> resultData = restTemplate.exchange(requestEntity, String.class);
System.out.println("从服务端返回结果: " + resultData);
}}
2.GET请求
2.1 GET请求方式1(getForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 2.处理GET请求
* 入参使用@RequestParam修饰
*/
@GetMapping("/f2")
public Object f2(@RequestParam("obj") String obj) {
log.info("RestfulController->f2,接收参数,obj = " + obj.toString());
log.info("RestfulController->f2,处理业务.");
log.info("RestfulController->f2,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f2();
}
/**
* 2.GET请求客户端
* 服务端入参注解: @RequestParam
* 客户端方法: getForObject
*/
public static void f2() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest/f2";
String obj = "Vue进阶教程";
String para = "?obj=" + obj;
getUrl = getUrl + para;
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.getForObject(getUrl, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
2.2 GET请求方式2(getForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 2.处理GET请求
* 入参使用@RequestParam修饰
*/
@GetMapping("/f2")
public Object f2(@RequestParam("obj") String obj) {
log.info("RestfulController->f2,接收参数,obj = " + obj.toString());
log.info("RestfulController->f2,处理业务.");
log.info("RestfulController->f2,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f2_1();
}
/**
* 2.1 GET请求客户端
* 服务端入参注解: @RequestParam
* 客户端方法: getForObject
* 客户端入参: 使用占位符和使用String类型传参
*/
public static void f2_1() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest/f2?&obj={obj}";
String obj = "Vue进阶教程";
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.getForObject(getUrl, String.class, obj);
System.out.println("从服务端返回结果: " + resultData);
}
}
2.3 GET请求方式3(getForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 2.处理GET请求
* 入参使用@RequestParam修饰
*/
@GetMapping("/f2")
public Object f2(@RequestParam("obj") String obj) {
log.info("RestfulController->f2,接收参数,obj = " + obj.toString());
log.info("RestfulController->f2,处理业务.");
log.info("RestfulController->f2,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f2_2();
}
/**
* 2.2 GET请求客户端
* 服务端入参注解: @RequestParam
* 客户端方法: getForObject
* 客户端入参: 使用占位符和使用Map类型传参
*/
public static void f2_2() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest/f2?&obj={obj}";
String obj = "Vue进阶教程Map";
Map<String, String> para = new HashMap<>();
para.put("obj", obj);
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.getForObject(getUrl, String.class, obj);
System.out.println("从服务端返回结果: " + resultData);
}
}
2.4 GET请求方式4(getForObject)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 3.处理GET请求
* 入参使用@PathVariable修饰
*/
@GetMapping("/f3/{obj}")
public Object f3(@PathVariable("obj") String obj) {
log.info("RestfulController->f3,接收参数,obj = " + obj.toString());
log.info("RestfulController->f3,处理业务.");
log.info("RestfulController->f3,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f3();
}
/**
* 3.使用RestTemplate调用服务端的GET请求
* 服务端入参注解: @PathVariable
*/
public static void f3() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest/f3/";
String obj = "Vue进阶教程";
getUrl = getUrl + obj;
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
String resultData = restTemplate.getForObject(getUrl, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
2.5 GET请求方式5(getForEntity)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 2.处理GET请求
* 入参使用@RequestParam修饰
*/
@GetMapping("/f2")
public Object f2(@RequestParam("obj") String obj) {
log.info("RestfulController->f2,接收参数,obj = " + obj.toString());
log.info("RestfulController->f2,处理业务.");
log.info("RestfulController->f2,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f2_3();
}
/**
* 2.3 GET请求客户端
* 服务端入参注解: @RequestParam
* 客户端使用方法: getForEntity
* 客户端返回值: ResponseEntity
*/
public static void f2_3() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest/f2";
String obj = "Vue进阶教程";
String para = "?obj=" + obj;
getUrl = getUrl + para;
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
ResponseEntity<String> resultData = restTemplate.getForEntity(getUrl, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
2.6 GET请求方式6(exchange)
/**
* 服务端类
*/
@Slf4j
@RestController
@RequestMapping(value = "/rest")
public class RestfulController {
/**
* 2.处理GET请求
* 入参使用@RequestParam修饰
*/
@GetMapping("/f2")
public Object f2(@RequestParam("obj") String obj) {
log.info("RestfulController->f2,接收参数,obj = " + obj.toString());
log.info("RestfulController->f2,处理业务.");
log.info("RestfulController->f2,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
/**
* 客户端类
*/
public class RestUtils {
public static void main(String[] args) throws Exception {
f2_4();
}
/**
* 2.4 GET请求客户端
* 服务端入参注解: @RequestParam
* 客户端方法: exchange
*/
public static void f2_4() throws Exception {
// 1.请求URL与组装请求参数
String getUrl = "http://127.0.0.1:19091/server/rest/f2";
String obj = "Vue进阶教程";
String para = "?obj=" + obj;
getUrl = getUrl + para;
// 2.创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 3.使用RestTemplate发起请求与接收返回值
ResponseEntity<String> resultData = restTemplate.exchange(getUrl,
HttpMethod.GET, null, String.class);
System.out.println("从服务端返回结果: " + resultData);
}
}
四、RestTemplate源码封装逻辑
本例以postForObject为例。
public <T> T postForObject(String url, @Nullable Object request,
Class<T> responseType, Object... uriVariables)
1.创建RestTemplate对象
创建RestTemplate对象,即初始化实例。
(1)加载响应错误处理器,即DefaultResponseErrorHandler。
(2)加载响应头部抽取器,即HeadersExtractor。
(3)加载一系列的http消息转换器,即HttpMessageConverter接口的各种实现类。
(4)初始化URI末班处理器。
RestTemplate restTemplate = new RestTemplate();
public RestTemplate() {
this.messageConverters = new ArrayList();
this.errorHandler = new DefaultResponseErrorHandler();
this.headersExtractor = new RestTemplate.HeadersExtractor();
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter(false));
if (!shouldIgnoreXml) {
try {
this.messageConverters.add(new SourceHttpMessageConverter());
} catch (Error var2) {
}
}
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
this.messageConverters.add(new AtomFeedHttpMessageConverter());
this.messageConverters.add(new RssChannelHttpMessageConverter());
}
if (!shouldIgnoreXml) {
if (jackson2XmlPresent) {
this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
} else if (jaxb2Present) {
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
}
if (jackson2Present) {
this.messageConverters.add(new MappingJackson2HttpMessageConverter());
} else if (gsonPresent) {
this.messageConverters.add(new GsonHttpMessageConverter());
} else if (jsonbPresent) {
this.messageConverters.add(new JsonbHttpMessageConverter());
} else if (kotlinSerializationJsonPresent) {
this.messageConverters.add(new KotlinSerializationJsonHttpMessageConverter());
}
if (jackson2SmilePresent) {
this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
}
if (jackson2CborPresent) {
this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
}
this.uriTemplateHandler = initUriTemplateHandler();
}
2.调用postForObject
触发调用postForObject。
(1)设置请求回调信息,即RequestCallback。
(2)设置http消息转换抽取器,即HttpMessageConverterExtractor。
(3)触发执行器调用,即execute。
@Nullable
public <T> T postForObject(String url, @Nullable Object request,
Class<T> responseType, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = this.httpEntityCallback(request, responseType);
HttpMessageConverterExtractor<T> responseExtractor =
new HttpMessageConverterExtractor(responseType, this.getMessageConverters(), this.logger);
return this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, (Object[])uriVariables);
}
3.调用execute
(1)获取URI信息
(2)触发调用doExecute,这是一个protected方法。
@Nullable
public <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException {
URI expanded = this.getUriTemplateHandler().expand(url, uriVariables);
return this.doExecute(expanded, method, requestCallback, responseExtractor);
}
4.调用doExecute
在RestTemplate中,doExecute是具体执行逻辑。
(1)创建ClientHttpRequest。
(2)调用ClientHttpRequest的execute具体执行。
(3)解析ClientHttpRequest的execute执行返回的ClientHttpResponse
(4)响应抽取器从ClientHttpResponse解析具体数据。
(5)在finally中关闭ClientHttpResponse数据流。
@Nullable
protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "URI is required");
Assert.notNull(method, "HttpMethod is required");
ClientHttpResponse response = null;
Object var14;
try {
ClientHttpRequest request = this.createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
this.handleResponse(url, method, response);
var14 = responseExtractor != null ? responseExtractor.extractData(response) : null;
} catch (IOException var12) {
String resource = url.toString();
String query = url.getRawQuery();
resource = query != null ? resource.substring(0, resource.indexOf(63)) : resource;
throw new ResourceAccessException("I/O error on " + method.name() + " request for \"" + resource + "\": " + var12.getMessage(), var12);
} finally {
if (response != null) {
response.close();
}
}
return var14;
}
以上,感谢。
2022年7月22日