SpringBoot (6)---RestTemplate方法详解(2)

说明

上一篇SpringBoot 2.1 | 第三篇:RestTemplate请求HTTP(1)简单运用了RestTemplate,
本篇主要讲解RestTemplate的主要请求方法, getForObjectgetForEntityexchange(方法列举只用了Get)。Method包括GET、POST、PUT、DELETE。参数传递,解析等。

在讲述使用之前,想要理解SpringMVC的几个常用注解:

  1. @Controller:修饰class,用来创建处理http请求的对象
  2. @RestController:Spring4之后加入的注解,原来在@Controller中返回json需要@ResponseBody来配合,如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,默认返回json格式。
  3. @RequestMapping:配置url映射
  4. @PostMapping: 这个是@RequestMapping+POST方法的简写
  5. @RequestHeader: 请求Header参数
  6. @PathVariable: URL路径参数,比如/user/{id}中的id参数
  7. @RequestParam: URL请求参数,比如/user?id=1中的id参数
  8. @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
调用方法包括GETPOSTPUTDELETE, 以及带参数的例子。
说明: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

调用的方法包括:getForObjectgetForEntityexchange(方法列举只用了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";}}

方法解说:

  1. HttpEntity的结构
    HttpEntity是对HTTP请求的封装,包含两部分,header与body,header用于设置请求头,而body则用于设置请求体,所以其的构造器如下:
//  value为请求体
//  header为请求头
HttpEntity<String> requestEntity = new HttpEntity<String>(value, headers);
  1. 后端处理前端提交的数据时,既可以使用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);
  1. 用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/demoresttemplatemethod

SpringBoot (6)---RestTemplate方法详解(2)相关推荐

  1. SpringBoot项目main方法详解

    前言 SpringBoot项目启动时通过执行main方法启动,main方法主要做了两方面工作: 初始化Spring容器 启动tomcat运行项目 下面我们通过源码来看如何进行的上面两个操作. 源码分析 ...

  2. html页面设置拦截器,SpringBoot拦截器Filter的使用方法详解

    SpringBoot拦截器Filter的使用方法详解 发布时间:2020-08-27 22:44:03 来源:脚本之家 阅读:107 作者:玉天恒 前言: 最新Servlet 3.0拦截器的使用 1. ...

  3. Springboot@Configuration和@Bean详解

    Springboot@Configuration和@Bean详解 一.@Configuration @Target({ElementType.TYPE}) @Retention(RetentionPo ...

  4. Springboot多数据源配置详解

    Springboot多数据源配置详解 概念 配置 多数据源使用 概念 一般来说,我们正常的业务只涉及一个数据源,在特定的业务场景中需要使用多个数据源的情况,就需要配置多个数据源来满足特定的业务需求.本 ...

  5. java函数方法详解(简单易懂)

    方法(函数) 函数的组成是: 访问修饰符 返回值 函数名(形式参数) {函数内容; } 更多java函数方法详解视频课程学习地址:https://ke.qq.com/course/149432  有技 ...

  6. java中drawimage方法_canvas.drawImage()方法详解

    首先看html5.js /** @param {Element} img_elem @param {Number} dx_or_sx @param {Number} dy_or_sy @param { ...

  7. SpringBoot定时任务@Scheduled注解详解

    SpringBoot定时任务@Scheduled注解详解 项目开发中,经常会遇到定时任务的场景,Spring提供了@Scheduled注解,方便进行定时任务的开发 概述 要使用@Scheduled注解 ...

  8. python统计csv行数_对Python 多线程统计所有csv文件的行数方法详解

    如下所示: #统计某文件夹下的所有csv文件的行数(多线程) import threading import csv import os class MyThreadLine(threading.Th ...

  9. python修改文件内容_Python批量修改文本文件内容的方法详解

    这篇文章主要介绍了Python批量修改文本文件内容的方法的相关资料,需要的朋友可以参考下 Python批量替换文件内容,支持嵌套文件夹 import os path="./" fo ...

最新文章

  1. shell脚本api接口考虑并发问题的可行性操作
  2. C++11 智能指针unique_ptr使用 -- 以排序二叉树为例
  3. mySql 注入攻击
  4. Docker安装及基本使用
  5. Boost:bind绑定__cdecl(成员函数)测试程序
  6. 用Java编写约分最简公式,2013年Java方向C组第五题
  7. 异步fifo_异步FIFO
  8. JavaScript学习(八十七)—流程控制语句的总结,超级详细!!!
  9. 自动化中间人攻击工具subterfuge小实验
  10. 聊一聊FPGA的片内资源相关知识
  11. 【文本匹配】Question Answering论文
  12. 181021词霸有道扇贝每日一句
  13. CAD 开发 渐变填充
  14. 默认暴露,分别暴露,整体暴露的再次学习及常用知识
  15. Dialog确认按钮不dismiss
  16. fancyhdr页眉页脚设计史上最全代码
  17. 基于深度学习的自动车牌识别(详细步骤+源码)
  18. python简单的预测模型_python简单预测模型
  19. Gimy 剧迷更新快,内容超多的电影、美日韩剧、动漫片源
  20. IMU数据仿真公式推导及代码实现

热门文章

  1. 【LeetCode】【HOT】301. 删除无效的括号(递归)
  2. Elasticsearch 性能监控2(五种常见问题的解决办法)
  3. SSH-远程登录协议
  4. java并发:interrupt进程终止
  5. https证书设置以及设置301跳转
  6. Windows 下python的tab自动补全
  7. [HEOI2013]ALO(待更)
  8. 第一阶段站立会议02
  9. viewport meta 标签在手机浏览器上控制布局
  10. 从excel导入数据库过程中遇到的空格转义符(#160;)