易筋SpringBoot 2.1 | 第四篇:RestTemplate方法详解(2)
写作时间:2018-12-27
Spring Boot: 2.1 ,JDK: 1.8, IDE: IntelliJ IDEA,
说明
上一篇SpringBoot 2.1 | 第三篇:RestTemplate请求HTTP(1)简单运用了RestTemplate,
本篇主要讲解RestTemplate的主要请求方法, getForObject
, getForEntity
, exchange
(方法列举只用了Get)。Method包括GET、POST、PUT、DELETE。参数传递,解析等。
在讲述使用之前,想要理解SpringMVC的几个常用注解:
@Controller
:修饰class,用来创建处理http请求的对象@RestController
:Spring4之后加入的注解,原来在@Controller
中返回json需要@ResponseBody
来配合,如果直接用@RestController
替代@Controller
就不需要再配置@ResponseBody
,默认返回json格式。@RequestMapping
:配置url映射@PostMapping
: 这个是@RequestMapping+POST方法的简写@RequestHeader
: 请求Header参数@PathVariable
: URL路径参数,比如/user/{id}中的id参数@RequestParam
: URL请求参数,比如/user?id=1中的id参数@RequestBody
: 请求Body参数
工程建立
参照教程【SpringBoot 2.1 | 第一篇:构建第一个SpringBoot工程】新建一个Spring Boot项目,名字叫demoresttemplatemethod, 在目录src/main/java/resources
下找到配置文件application.properties
,重命名为application.yml
。
创建RestTemplateConfig配置类
请求都需要用到restTemplate
对象,用@Bean的方式注入,用同一个工厂对象统一管理ClientHttpRequestFactory
。
新建类:
com.zgpeace.demoresttemplatemethod.configure.RestTemplateConfig
package com.zgpeace.demoresttemplatemethod.configure;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;@Configuration
public class RestTemplateConfig {@Beanpublic RestTemplate restTemplate(ClientHttpRequestFactory factory) {return new RestTemplate(factory);}@Beanpublic ClientHttpRequestFactory simpleClientHttpRequestFactory() {SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();factory.setReadTimeout(5000);//msfactory.setConnectTimeout(15000);//msreturn factory;}
}
创建Model对象User
结果实体User用于数据传递,新建类
com.zgpeace.demoresttemplatemethod.model.User
package com.zgpeace.demoresttemplatemethod.model;public class User {private Integer id;private String methodName;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getMethodName() {return methodName;}public void setMethodName(String methodName) {this.methodName = methodName;}@Overridepublic String toString() {return "User{" +"id=" + id +", methodName='" + methodName + '\'' +'}';}
}
创建Restful被调用类
REST,即Representational State Transfer的缩写,对这个词组的翻译是表现层状态转化。
RESTful是一种软件设计风格,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
这里为了演示,会将数据保存到内存Map中,实际使用肯定是保存到数据库中。
创建Restful被调用类:
com.zgpeace.demoresttemplatemethod.web.UserController
调用方法包括GET、POST、PUT、DELETE, 以及带参数的例子。
说明:PUT是幂等性方法,也就是请求多次跟一次的效果一样,就像微信转账一样,一次转账弱网情况下可能会重试,但是结果不会因为多次尝试而不一样, 一般用户更新。而POST不是幂等性的方法,也就是多次重试,会有多个结果,一般用于创建。
package com.zgpeace.demoresttemplatemethod.web;import com.zgpeace.demoresttemplatemethod.model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@RequestMapping(value = "/testGet", method = RequestMethod.GET)public User testGet() {User user = new User();user.setId(1);user.setMethodName("get");return user;}@RequestMapping(value = "/testPost", method = RequestMethod.POST)public User testPost() {User user = new User();user.setId(1);user.setMethodName("post");return user;}@RequestMapping(value = "/testPostParam", method = RequestMethod.POST)public String testPostParam(@RequestParam("id") String id, @RequestParam("methodName") String methodName) {System.out.println("Post id: " + id);System.out.println("Post methodName: " + methodName);return "post id{" + id + "} success";}@RequestMapping(value = "/testPut", method = RequestMethod.PUT)public String testPut(@RequestParam("id") String id, @RequestParam("methodName") String methodName) {System.out.println("put id: " + id);System.out.println("put methodName: " + methodName);return "put id{" + id + "} success";}@RequestMapping(value = "/testDel", method = RequestMethod.DELETE)public String testDel(@RequestParam("id") String id) {System.out.println("del id: " + id);return "del id{" + id + "} success";}}
RequestParam解析:
例子:@RequestParam(value = "name", required = true, defaultValue = "defaultName"
@RequestParam 支持下面四种参数
name 绑定本次参数的名称,要跟URL上面的一样
value 跟name一样的作用,是name属性的一个别名
defaultValue 如果本次请求没有携带这个参数,或者参数为空,那么就会启用默认值
required 这个参数是不是必须的
创建使用RestTemplate调用Rest接口的Controller
调用的方法包括:getForObject
, getForEntity
, exchange
(方法列举只用了Get,Method包括GET、POST、PUT、DELETE).
新建类com.zgpeace.demoresttemplatemethod.web.UserRequestController
package com.zgpeace.demoresttemplatemethod.web;import com.zgpeace.demoresttemplatemethod.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.net.URI;
import java.net.URISyntaxException;@RestController
public class UserRequestController {@Autowiredprivate RestTemplate restTemplate;private static String PROTOCOL = "http";private static String HOST = "localhost";private static String PORT = "8080";private static String PRE_URL = PROTOCOL + "://" + HOST + ":" + PORT + "/";private static String GET_URL = PRE_URL + "testGet";private static String POST_URL = PRE_URL + "testPost";private static String POST_PARAM_URL = PRE_URL + "testPostParam";private static String PUT_URL = PRE_URL + "testPut";private static String DEL_URL = PRE_URL + "testDel";@GetMapping("/requestTestGet")public String requestTestGet() throws URISyntaxException {// 1. getForObject()User user1 = restTemplate.getForObject(GET_URL, User.class);System.out.println("get user1: " + user1);// 2. getForEntity()ResponseEntity<User> responseEntity1 = restTemplate.getForEntity(GET_URL, User.class);HttpStatus statusCode = responseEntity1.getStatusCode();HttpHeaders header = responseEntity1.getHeaders();User user2 = responseEntity1.getBody();System.out.println("get user2: " + user2);System.out.println("get statusCode: " + statusCode);System.out.println("get header: " + header);// 3. exchange()RequestEntity requestEntity = RequestEntity.get(new URI(GET_URL)).build();ResponseEntity<User> responseEntity2 = restTemplate.exchange(requestEntity, User.class);User user3 = responseEntity2.getBody();System.out.println("get user3: " + user3);return "requestTestGet";}@GetMapping("/requestTestPost")public String requestTestPost() throws URISyntaxException {HttpHeaders headers = new HttpHeaders();String data = new String();HttpEntity<String> formEntity = new HttpEntity<String>(data, headers);// 1. postForObject()User user1 = restTemplate.postForObject(POST_URL, formEntity, User.class);System.out.println("post user1: " + user1);// 2. postForEntity()ResponseEntity<User> responseEntity1 = restTemplate.postForEntity(POST_URL, formEntity, User.class);HttpStatus statusCode = responseEntity1.getStatusCode();HttpHeaders header = responseEntity1.getHeaders();User user2 = responseEntity1.getBody();System.out.println("post user2: " + user2);System.out.println("post statusCode: " + statusCode);System.out.println("post header: " + header);// 3. exchange()RequestEntity requestEntity = RequestEntity.post(new URI(POST_URL)).body(formEntity);ResponseEntity<User> responseEntity2 = restTemplate.exchange(requestEntity, User.class);User user3 = responseEntity2.getBody();System.out.println("post user3: " + user3);return "requestTestPost";}@GetMapping("/requestTestPostParam")public String requestTestPostParam() {HttpHeaders headers = new HttpHeaders();MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();map.add("id", "100");map.add("methodName", "requestTestPostParam");HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);String data = restTemplate.postForObject(POST_PARAM_URL, request, String.class);System.out.println("requestTestPostParam data: " + data);System.out.println("requestTestPostParam success");return "requestTestPostParam";}@GetMapping("requestTestPut")public String requestTestPut() {MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();map.add("id", "101");map.add("methodName", "requestTestPut");restTemplate.put(PUT_URL, map);System.out.println("requestTestPut success");return "requestTestPut";}@GetMapping("requestTestDel")public String requestTestDel() {HttpHeaders headers = new HttpHeaders();// 请勿轻易改变此提交方式,大部分的情况下,提交方式都是表单提交headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);// 封装参数,千万不要替换为Map与HashMap,否则参数无法传递MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();map.add("id", "101");map.add("methodName", "requestTestDel");HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(map, headers);// 方法一ResponseEntity<String> resp = restTemplate.exchange(DEL_URL , HttpMethod.DELETE, requestEntity, String.class, 227);System.out.println("requestTestDel response: " + resp.getBody());// 方法二
// restTemplate.delete(DEL_URL + "?id={id}", 102);System.out.println("requestTestDel success");return "requestTestDel";}}
方法解说:
- HttpEntity的结构
HttpEntity是对HTTP请求的封装,包含两部分,header与body,header用于设置请求头,而body则用于设置请求体,所以其的构造器如下:
// value为请求体
// header为请求头
HttpEntity<String> requestEntity = new HttpEntity<String>(value, headers);
- 后端处理前端提交的数据时,既可以使用Form解析,也可以使用JSON解析Payload字符串。
Form解析可以直接从Request对象中获取请求参数,这样对象转换与处理相对容易,但在大片JSON数据需要提交时,可能会出现大量的数据拆分与处理工作,另外针对集合类型的处理,也是其比较孱弱的地方。
而Payload的优势是一次可以提交大量JSON字符串,但无法从Request从获取参数,也会受限于JSON解析的深度(尤其是有多层对象级联的情况,最底层的对象几乎无法转换为具体类型)。
HttpHeaders headers = new HttpHeaders();// form表单提交headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);// payload提交headers.setContentType(MediaType.APPLICATION_JSON);
- 用exchange方法提交
exchange可以执行所有HTTP的方法(GET、POST、PUT、DELETE、HEAD).
HttpEntity封装参数的时候必须用MultiValueMap,千万不要替换为Map与HashMap,否则参数无法传递。
// 封装参数,MultiValueMap千万不要替换为Map与HashMap,否则参数无法传递MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();map.add("id", "101");map.add("methodName", "requestTestDel");HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(map, headers);
运行结果,控制台打印信息:
requestTestGet运行输出
get user1: User{id=1, methodName='get'}
get user2: User{id=1, methodName='get'}
get statusCode: 200 OK
get header: {Content-Type=[application/json;charset=UTF-8], Transfer-Encoding=[chunked], Date=[Thu, 27 Dec 2018 10:28:22 GMT]}
get user3: User{id=1, methodName='get'}
requestTestPost运行输出
post user1: User{id=1, methodName='post'}
post user2: User{id=1, methodName='post'}
post statusCode: 200 OK
post header: {Content-Type=[application/json;charset=UTF-8], Transfer-Encoding=[chunked], Date=[Thu, 27 Dec 2018 10:29:50 GMT]}
post user3: User{id=1, methodName='post'}
requestTestPostParam运行输出
PostParam id: 100
PostParam methodName: requestTestPostParam
requestTestPostParam data: post id{100} success
requestTestPostParam success
requestTestPut运行输出
put id: 101
put methodName: requestTestPut
requestTestPut success
requestTestDel运行输出
requestTestDel before
del id: 101
requestTestDel response: del id{101} success
requestTestDel success
总结
恭喜你! 已经完成RestTemplate中的常用方法用法。
代码下载:
https://github.com/zgpeace/Spring-Boot2.1/tree/master/http/demoresttemplatemethod
参考:
https://my.oschina.net/sdlvzg/blog/1800395
https://blog.csdn.net/yiifaa/article/details/77939282
https://blog.csdn.net/yiifaa/article/details/73468001
https://www.xncoding.com/2017/07/05/spring/sb-restful.html
易筋SpringBoot 2.1 | 第四篇:RestTemplate方法详解(2)相关推荐
- SpringBoot (6)---RestTemplate方法详解(2)
SpringBoot (6)---RestTemplate方法详解(2) 说明 上一篇SpringBoot 2.1 | 第三篇:RestTemplate请求HTTP(1)简单运用了RestTempla ...
- spring之旅第四篇-注解配置详解
spring之旅第四篇-注解配置详解 一.引言 最近因为找工作,导致很长时间没有更新,找工作的时候你会明白浪费的时间后面都是要还的,现在的每一点努力,将来也会给你回报的,但行好事,莫问前程!努力总不会 ...
- MySQL数据库,从入门到精通:第十四篇——MySQL视图详解
MySQL数据库,从入门到精通:第十四篇--MySQL视图详解 第 14 篇_视图 1. 常见的数据库对象 2. 视图概述 2. 1 为什么使用视图? 2. 2 视图的理解 3. 创建视图 3. 1 ...
- DAX 第四篇:CALCULATE详解
CALCULATE()函数是DAX中最复杂的函数,用于计算由指定过滤器修改的上下文中的表达式. CALCULATE(<expression>,<filter1>,<fil ...
- MySQL数据库,从入门到精通:第十二篇——MySQL数据类型详解
MySQL数据库,从入门到精通:第十二篇--MySQL数据类型详解 第 12 章_MySQL数据类型精讲 1. MySQL中的数据类型 2. 整数类型 2. 1 类型介绍 2. 2 可选属性 2. 2 ...
- spring boot(四):thymeleaf使用详解
spring boot(四):thymeleaf使用详解 在上篇文章springboot(二):web综合开发中简单介绍了一下thymeleaf,这篇文章将更加全面详细的介绍thymeleaf的使用. ...
- 【备战春招/秋招系列】美团Java面经总结进阶篇 (附详解答案)
<!-- MarkdownTOC --> 一 消息队列MQ的套路 1.1 介绍一下消息队列MQ的应用场景/使用消息队列的好处 ①.通过异步处理提高系统性能 ②.降低系统耦合性 1.2 那么 ...
- 【备战春招/秋招系列】美团Java面经总结终结篇 (附详解答案)
该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 14 k).地址:https://github.com/Snailclimb.. ...
- 【备战春招/秋招系列】美团Java面经总结终结篇 (附详解答案) 1
该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 14 k).地址:https://github.com/Snailclimb/J ...
- 入木三分学网络第一篇--VRRP协议详解-----(1)
原帖:http://blog.chinaunix.net/uid-11654074-id-2857384.html 目录 入木三分学网络第一篇--VRRP协议详解 1. VRRP产生背景及应用环境 1 ...
最新文章
- 文件格式 tar.gz zip zp2 zip rar
- yl335b分拣站单元流程图_选择单元化物流容器的必要性
- Kotlin-Learning 扩展
- java重定向设置header_java – 重定向时将标题添加到Zuul
- 【python 3.6】python读取json数据存入MySQL(一)
- Android Sdk 国内镜像下载地址
- linux进程映像由哪些构成,Linux编程开发进程映像类型分析
- vue实现一个带搜索功能的列表_(Vue起步)2.模板指令:v-for / v-on / v-model
- python提醒事件_监控服务器空间使用情况-crontab+python邮件提醒
- mysql5.7.22.zip使用,mysql5.7.22 zip 版安装
- python手写计算器
- 信息化和信息系统-PMP
- AVFoundation音视频采集(三)
- 滴滴CTO张博港科大演讲:详解未来交通变革的三层“折叠”
- 【SAP打印】SMARTFORMS标签无法调整横向打印
- 广域网的基本概念和技术特点
- js 2020常见面试题
- 读 伯罗奔尼撒战争史
- 用PHP来统计在线人数的四个方法详解
- [ChatGPT为你支招]如何提高博客的质量,找到写作方向,保持动力,增加粉丝数?
热门文章
- -f linux_SAIL-F-8-2-4-0-12流量积算仪-老友网
- vscode中打开pdf文件_Visual Studio Code Preview深度体验、使用技巧.pdf
- SQLServer如何在批量插入后,获取批量插入的自增列的值
- vmware workstation虚拟环境安装及创建虚拟机
- Java面试应该准备的知识点系列一
- 【mybatis深度历险系列】mybatis中的动态sql
- 对代码更有信心--单元测试工具Mockito简单介绍
- (转)iOS Wow体验 - 第六章 - 交互模型与创新的产品概念(1)
- window自动生成数据库连接字符串
- 091030 T 焦点在外,框架API设计