RestTemplate的详解

2023-11-05

引言
在SpringCloud微服务中,通过引入 ribbon实现了服务消费者的客户端负载均衡功能,在这个过程中使用了一个非常有用的对象 RestTemplate。 该对象会使用 Ribbon 的自动化配置, 同时通过配置@LoadBalanced 还能够开启客户端负载均衡。
下面我们将详细介绍 RestTemplate 针对几种不同请求类型和参数类型的服务调用实现。
一、 GET请求
在 RestTemplate 中, 对 GET 请求可以通过如下两个方法进行调用实现。
第一种: getForEntity 函数。该方法返回的是 ResponseEntity, 该对象是 Spring对 HTTP 请求响应的封装, 其中主要存储了 HTTP 的几个重要元素, 比如 HTTP 请求状态码的枚举对象 HttpStatus (也就是我们常说的 404、 500 这些错误码)、 在它的父类httpEntity中还存储着 HTTP 请求的头信息对象 HettpHeaders 以及泛型类型的请求体对象。 比如下面的例子, 就是访问 USER-SERVER 服务的/user 请求, 同时最后一个参数didi 会替换 url 中的{1} 占位符, 而返回的 ResponseEntity对象中的 body 内容类型会根据第二个参数转换为 String 类型。

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://USERSERVICE/user?name= { 1} ", String. class, "didi") ;
String body = responseEntity. getBody () ;

若我们希望返回的 body 是一个 User 对象类型, 也可以这样实现:

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<User> responseEntity = restTemplate.getForEntity("http://USERSERVICE/user?name= {l}", User.class, "didi");
User body= responseEntity.getBody();

上面的例子是比较常用的方法,getForEntity 函数实际上提供了以下三种不同的重载实现。
getForEntity(String url, Class responseType, Object … urlVariables):
该方法提供 了三个参数, 其中 url为请求的地址, responseType 为请求响应体
body 的包装类型, urlVariables为url 中的参数绑定。 GET 请求的参数绑定通常使用url 中拼接的方式, 比如 http://USER-SERVICE/user?name=did,我们可以像这样自已将参数拼接到 url 中,但更好的方法是在url 中使用占位符并配urlVariables 参数实现 GET请求的参数绑定, 比 如 url 定义为
http://USER-SERVICE/user?name= {1}, 然后可以这样来调用: getForEntity
(“http://USER-SERVICE/user?name= {l}”, String.class, “didi”)’ 其中第三个参数 didi 会替换 url 中的{ 1} 占位符。 这里需要注意的是, 由千urlVariables 参数是一个数组, 所以它的顺序会对应 url 中 占位符定义的数字顺序。
• getForEntity(String url, Class responseType, Map urlVariables):
该方法提供的参数中, 只有 urlVariables 的参数类型与上面的方法不同。 这里使用了 Map 类型, 所以使用该方法进行参数绑定时需要在占位符中指定Map 中参数的 key 值, 比如 url定义为 http://USER-SERVICE/user?name= {name),
在Map 类型的 urlVariables 中, 我们就需要 put 一个 key为 name 的参数来绑
定url 中 {name} 占位符的值, 比如:

RestTemplate restTemplate = new RestTemplate();
Map<String, String> params = new HashMap<>();
params.put("name", "dada");
ResponseEntity<String> responseEntity = restTemplate.getForEntity("h七tp://USERSERVICE/user?name={name}", String.class, params);

getForEntity(URl url, Class responseType):
该方法使用URI 对象来替代之前的 url 和 urlVariables 参数来指定访问地址和参数绑定。 URI 是JDK java.net 包下的一个类,它表示一个统一资源标识符(Uniform Resource Identifier)
引用。 比如下面的例子:

RestTemplate restTemplate = new RestTemplate();
UriComponents uriComponents = UriComponentsBuilder.fromUriString(
"http://USER-SERVICE/user?name={name}")
.build()
. expand ("dodo")
.encode();
URI uri = uriComponents.toUri();
ResponseEntity<String> responseEntity = restTemplate.getForEntity(uri,
String. class) . getBody () ;

更多关于如何定义 一个 URI 的方法可以参见 JDK 文档, 这里不做详细说明。
第二种: getForObject 函数。
该方法可以理解为对 getForEntity 的进一步封装,
它通过 HttpMessageConverterExtractor 对 HTTP 的请求响应体 body内容进行对象转换, 实现请求直接返回包装好的对象内容。 比如:
RestTemplate restTemplate = new Rest Template() ;
String result = restTemplate.getForObject(uri, String.class);
当 body是一个 User 对象时, 可以直接这样实现:
RestTemplate restTemplate = new RestTemplate();
User result = restTemplate.getForObject(uri, User.class);
当不需要关注请求响应除 body 外的其他内容时, 该函数就非常好用, 可以少一个从
Response 中获取 body的步骤。 它与 getForEn巨ty 函数类似, 也提供了三种不同的重载实现。
• getForObject (String url, Class responseType, Object. … urlVariables):
与 getForEntity 的方法类似, url 参数指定访问的地址, responseType 参数定义该方法的返回类型, urlVariables 参数为 url 中占位符对应的参数。
• getForObject(String url, Class responseType, Map urlVariables):
在该函数中,使用 Map 类型的 urlVariables 替代上面数组形式的 urlVariables,
因此使用时在 url 中需要将占位符的名称与 Map 类型中的 key-一 一对应设置。
• getForObject(URL url, Class responseType): 该方法使用 URI 对象来
替代之前的 url和urlVariables 参数使用。
二、POST请求
在 RestTemplate 中, 对 POST 请求时可以通过如下三个方法进行调用实现。
第一种: postForEntity 函数
该方法同 GET 请求中的 ge七ForEntity 类似, 会
在调用后返回 ResponseEntity对象, 其中 T 为请求响应的 body类型。 比如下面这
个例子, 使用 postForEntity 提交 POST 请求到 USER-SERVICE 服务的/user 接口,
提交的 body内容为 user 对象, 请求响应返回的 body类型为 String。

RestTemplate restTemplate = new RestTemplate();
User user = new User("didi", 30);
ResponseEntity<String> responseEntity =
restTemplate.postForEntity("http://USER-SERVICE/user", user, String.class);
String body = responseEntity.getBody();

postForEntity 函数也实现了三种不同的重载方法。
postForEntiity(String url, Object request, Class responseType,Object … uri Variables)
• postForEntiity(String url, Object request, Class responseType,Map uri Variables)
• postForEntity(URI url, Object request, Class responseType)
这些函数中的参数用法大部分与getForEntity 一致, 比如, 第一个重载函数和第二个重载函数中的 uriVariables 参 数都用来对 url 中的参数进行绑定使用;
responseType参数是对请求响应的body内容的类型定义。 这里需要注意的是新增加的request参数, 该参数可以是 一个普通对象, 也可以是 一个HttpEntity对象。 如果是一个普通对象, 而非HttpEntity对象的时候, RestTemplate会将请求对象转换为一个HttpEntity对象来处理, 其中Object就是 request的类型, request内容会被视作完整的body来处理;而如果 request是 一个HttpEntity对象, 那么就会被当作一个完成的HTTP请求对象来处理, 这个 request中不仅包含了body的内容, 也包含了header的内容。
第二种: postForObject函数。
该方法也跟getForObject的类型类似, 它的作
用是简化postForEntity的后续处理。 通过直接将请求响应的body内容包装成对象来返回使用, 比如下面的例子:

RestTemplate restTemplate = new RestTemplate();
User user = new User("didi", 20);
String postResult = restTemplate.postForObject("http: //USER-SERVICE/user", user,
String.class);

postForObject函数也实现了三种不同的重载方法:
• postForObject(String url, Object request, Class responseType,
Object … uri Variables)
• postForObject(String url, Object request, Class responseType,
Map uriVariables)
• postForObject(URI url, Object request, Class responseType)

这三个函数除了返回的对象类型不同, 函数的传入参数均与postForEntity 一致,
因此可参考之前postForEntity的说明。
第三种: postForLocation函数
该方法实现了以POST请求提交资源, 并返回新
资源的URI, 比如下面的例子:

User user = new User("didi", 40);
URI responseURI = rest Template. postForLocation ("http:/ /USER-SERVICE/user", user);

postForLocation函数也实现了三种不同的重载方法:
• postForLocation (String url, Object request, Object … url Variables)
• postForLocation(String url, Object request, Map urlVariables)
• postForLocation(URI url, Object request)

由于 postForLocation函数会返回新资源的URI, 该URI就相当于指定了返回类型,所以此方法实现的POST请求不需要像postForEntity和postForObject那样指
定responseType。 其他的参数用法相同。
三、PUT请求
在RestTemplate中,对PUT请求可以通过put方法 进行调用实现,比如:

RestTemplate restTemplate = new RestTemplate ();
Long id = 100011;
User user = new User("didi", 40);
restTempla七e.put("http://USER-SERVICE/user/{l}", user, id);

put函数也实现 了三种不同的重载方法:
• put(String url, Object request, Object … urlVariables)
• put(S七ring url, Object request, Map urlVariables)
• put(URI url, Object request)

put函数为void类型,所以没有返回内容,也就没有其他函数定义的responseType参数, 除此之外的其他传入参数定义与用法与pastForObject基本一致。
四、DELETE请求
在RestTemplate中,对DELETE请求可以通过delete方法进行调用实现,比如:

RestTemplate restTemplate = new ResTemplate();
Long id= 10001L;
restTemplate.delete("http://USER-SERVICE/user/{1)", id);

delete函数也实现了三种不同的重载方法:
• delete(String url, Object … urlVariables)
• delete(String url, Map urlVariables)
• delete(URI url)

由于我们在进行REST请求时, 通常都将DELETE请求的唯一标识拼接在url中,所以DELETE请求也不需要request的body信息,就如上面的三个函数实现 一 样,非常简单。
url指定DELETE请求的位置, urlVariables绑定url中的参数即可。
附:
HTTP请求的状态码
(1)成功Successful2xx:此类状态码标识客户端的请求被成功接收、理解并接受。常见如200(OK)、204(NoContent)。
(2)重定向Redirection3xx:这个类别的状态码标识用户代理要做出进一步的动作来完成请求。常见如301(MovedPermanently)、302(MovedTemprarily)。
(3)客户端错误Client Error 4xx:4xx类别的状态码是当客户端象是出错的时使用的。常见如400(BadRequest)、401(Unauthorized)、403(Forbidden)、404(NotFound)。
(4)服务器错误Server Error 5xx:响应状态码以5开头表示服务器知道自己出错或者没有能力执行请求。常见如500(InternalServer Error)、502(BadGateway)、504(GatewayTimeout)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RestTemplate的详解 的相关文章

  • Java中有没有一种方法可以通过名称实例化一个类?

    我正在寻找问题 从字符串名称实例化一个类 https stackoverflow com questions 9854900 instantiate an class from its string name它描述了如何在有名称的情况下实例
  • 序列的排列?

    我有具体数量的数字 现在我想以某种方式显示这个序列的所有可能的排列 例如 如果数字数量为3 我想显示 0 0 0 0 0 1 0 0 2 0 1 0 0 1 1 0 1 2 0 2 0 0 2 1 0 2 2 1 0 0 1 0 1 1 0
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • 来自 dll 的 Java 调用函数

    我有这个 python 脚本导入zkemkeeperdll 并连接到考勤设备 ZKTeco 这是我正在使用的脚本 from win32com client import Dispatch zk Dispatch zkemkeeper ZKE
  • 在 junit 测试中获取 javax.lang.model.element.Element 类

    我想测试我的实用程序类 ElementUtils 但我不知道如何将类作为元素获取 在 AnnotationProcessors 中 我使用以下代码获取元素 Set
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 如何访问JAR文件中的Maven资源? [复制]

    这个问题在这里已经有答案了 我有一个使用 Maven 构建的 Java 应用程序 我有一个资源文件夹com pkg resources 我需要从中访问文件 例如directory txt 我一直在查看各种教程和其他答案 但似乎没有一个对我有
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • 尝试将 Web 服务部署到 TomEE 时出现“找不到...的 appInfo”

    我有一个非常简单的项目 用于培训目的 它是一个 RESTful Web 服务 我使用 js css 和 html 创建了一个客户端 我正在尝试将该服务部署到 TomEE 这是我尝试部署时遇到的错误 我在这里做错了什么 刚刚遇到这个问题 我曾
  • 为什么 Java 8 不允许非公共默认方法?

    让我们举个例子 public interface Testerface default public String example return Hello public class Tester implements Testerface
  • Eclipse 选项卡宽度不变

    我浏览了一些与此相关的帖子 但它们似乎并不能帮助我解决我的问题 我有一个项目 其中 java 文件以 2 个空格的宽度缩进 我想将所有内容更改为 4 空格宽度 我尝试了 正确的缩进 选项 但当我将几行修改为 4 空格缩进时 它只是将所有内容
  • Cucumber 0.4.3 (cuke4duke) 与 java + maven gem 问题

    我最近开始为 Cucumber 安装一个示例项目 并尝试使用 maven java 运行它 我遵循了这个指南 http www goodercode com wp using cucumber tests with maven and ja
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • 我如何在java中读取二进制数据文件

    因此 我正在为学校做一个项目 我需要读取二进制数据文件并使用它来生成角色的统计数据 例如力量和智慧 它的设置是让前 8 位组成一个统计数据 我想知道执行此操作的实际语法是什么 是不是就像读文本文件一样 这样 File file new Fi
  • 长轮询会冻结浏览器并阻止其他 ajax 请求

    我正在尝试在我的中实现长轮询Spring MVC Web 应用程序 http static springsource org spring docs 2 0 x reference mvc html但在 4 5 个连续 AJAX 请求后它会
  • CamcorderProfile.videoCodec 返回错误值

    根据docs https developer android com reference android media CamcorderProfile html 您可以使用CamcorderProfile获取设备默认视频编解码格式 然后将其
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db
  • Spring Rest 和 Jsonp

    我正在尝试让我的 Spring Rest 控制器返回jsonp但我没有快乐 如果我想返回 json 但我有返回的要求 完全相同的代码可以正常工作jsonp我添加了一个转换器 我在网上找到了用于执行 jsonp 转换的源代码 我正在使用 Sp

随机推荐

  • 拒绝后门程序-Alibabaprotect和AliPaladin

    详细参考帖子及评论区 流氓进程AlibabaProtect的删除 程序员吧 百度贴吧 首先打开服务找到AlibabaProtect 然后找到他的位置 C Program Files x86 AlibabaProtect 这个目录下有个uni
  • 巧解高并发之福利抽奖

    随着互联网的发展 高并发问题几乎是每个企业都会面临的问题 而目前解决高并发最受欢迎的便是微服务 通过类似于增加服务器数量而达到一种 人多力量大的 效果 但是 类似方法均需要技术及资本的支持 而当现有技术和资本不达标时 一切都是空谈 那么当技
  • mysql 数据多表join

    0 索引 JOIN语句的执行顺序 INNER LEFT RIGHT FULL JOIN的区别 ON和WHERE的区别 1 概述 一个完整的SQL语句中会被拆分成多个子句 子句的执行过程中会产生虚拟表 vt 但是结果只返回最后一张虚拟表 从这
  • 在cmd/bat脚本中获取当前脚本文件所在目录

    Q 在Win7 Win10中以管理员身份运行在cmd bat脚本时 如何获取当前脚本文件所在目录 当我们在Win7 Win10中使用鼠标右键的 以管理员身份运行 以管理员身份运行cmd bat脚本时 系统默认进入的目录是C Windows
  • 【Burp Suite】配置FireFox火狐浏览器burpsuite https抓包

    配置FireFox火狐浏览器burpsuite https抓包 配置火狐浏览器代理 Firefox配置证书 FireFox再配置代理 抓包 成功
  • centos7 安装mysql8.0

    1 官方文档 http dev mysql com doc mysql yum repo quick guide en 2 下载 Mysql yum包 http dev mysql com downloads repo yum 或者直接 w
  • VMware虚拟机安装+Ubuntu下载+VMware虚拟机配置运行

    一 安装虚拟机VMware 1 下载地址 下载 VMware Workstation Pro CN 2 进入官网 点击Window 16 Pro for Windows即可立即下载 3 下载好后 如图所示 4 运行exe文件 进入VMwar
  • Klipper seria.c 文件代码分析

    一 前言 Klipper 底层硬件的串口模块程序写的是否正确是决定下位机与上位机能否正常通信的前提 如果这个文件的驱动没写好 那上位机控制下位机就无从谈起 更无法通过上位机去验证下位机程序的正确性 本篇博文将详细解析 Klipper src
  • ORA-00933: SQL命令未正确结束 解决办法

    1 报错内容 Cause java sql SQLSyntaxErrorException ORA 00933 SQL 命令未正确结束 bad SQL grammar nested exception is java sql SQLSynt
  • SpringBoot原理解析(超详细)

    SpringBoot原理解析 1 SpringBootApplication原理解析 首先 我们直接追踪 SpringBootApplication的源码 Target ElementType TYPE Retention Retentio
  • JMeter获取数据库数据作为接口参数

    1 既然是操作数据库肯定具备需要对数据库的配置 2 在接口测试的过程中有OA需要进行账号切换 因此在这里利用sql直接查询数据 3 且看配置 variables names设置为A C 那么如下变量会被设置为 A 2 总行数 A 1 第1列
  • python爬取微信公众号文章

    爬取微信公众号文章 获取微信公众号的url 获取每一篇文章的url 选择一个公众号进入 选择一个目录进入后点复制链接 然后去浏览器打开 按F12打开检查的模式 在Console中输入 x 标签路径 找到子文章的目录xpath 然后分离出每篇
  • UDP实现点对点聊天-C语言

    UDP实现点对点聊天 服务器端 操作步骤 1 编译 gcc UDPSt c lws2 32 o UDPSt exe 2 运行 UDPSt include
  • 2021年蓝桥杯c++b组解析(个人)

    随着蓝桥杯不断地推进 期间也要多加练习才能有所收获 对于这份去年的试卷 个人感觉有些难度 具体体现在数字大 状态方程难想 对于后四题编程都有所难度 本人也只能通过40 60 的样例 下面针对下面10个题进行系统讲解 部分代码与思路源于网上
  • 苹果M1芯片上运行Stable Diffusion(文字作画)

    1 源码下载 git clone b apple silicon mps support https github com bfirsh stable diffusion git cd stable diffusion 2 修改gitee国
  • 聚观早报

    今日要闻 谷歌发布全球最大视觉语言模型 马斯克预计Twitter下季度现金流转正 王兴投资王慧文ChatGPT项目 美国拟明年 11 月开展载人绕月飞行 慧与科技宣布收购Athonet 谷歌发布全球最大视觉语言模型 近日 来自谷歌和德国柏林
  • Python学生信息管理系统【GUI界面版 + 期末报告书 + 功能实现讲解】

    课程设计说明 GUI 使用的是Python自带的 tkinter 模块 无需配置 Python自带的模块直接导包使用即可 包含了增删改查 保存文件 满足 90 大学生期末课程设计需求 运行时在main py文件右键运行即可 完整文件关注私聊
  • 进程间通信--管道通信

    进程间通信 在两个进程之间 每个进程各自有不同的用户地址空间 任何一个进程的全局变量在另一个进程中都看不到 比如 在父进程中的全局变量 如果在子进程中去改变这个全局变量 则子进程中被改变的这个值不会去影响父进程 因为子进程中的所有数据都是通
  • Visual Studio 2022 常用快捷键,记录一下别忘记~

    Visual Studio 2022 常用快捷键 记录一下别忘记 Ctrl E C 注释代码 Ctrl E U 取消注释代码 Ctrl E D 格式化全部代码 Ctrl Shift A 新建类 Ctrl R G 删除无效Using Ctrl
  • RestTemplate的详解

    引言 在SpringCloud微服务中 通过引入 ribbon实现了服务消费者的客户端负载均衡功能 在这个过程中使用了一个非常有用的对象 RestTemplate 该对象会使用 Ribbon 的自动化配置 同时通过配置 LoadBalanc