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的详解 的相关文章

  • 如何创建约束输入流以仅读取文件的一部分?

    我想创建一个仅限于文件中一定范围的字节的输入流 例如从位置 0 到 100 的字节 这样 一旦到达第 100 个字节 客户端代码就应该看到 EOF The read 的方法InputStream一次读取一个字节 你可以写一个子类InputS
  • 在eclipse java项目中加载dll文件

    我正在尝试添加文件sqljdbc auth dll到项目库 我将包含 dll 的文件夹添加为外部类文件夹 在这里 我基本上尝试使用 Microsoft 提供的 SQL 驱动程序连接到我的 SQL SERVER 2008 数据库 我的代码是
  • JAX-RS:不区分大小写的路径

    我已将 REST 服务 方法锚定到 URI 模板 Path注解 它看起来像往常一样 GET Path message Produces application json public Response getMessage 但我的 REST
  • PHP 和 ESB(使用 Mule)(ESB:企业服务总线)

    您在 PHP 项目中何时 何地以及为何使用 ESB 您认为在何处 何时以及为何在 PHP 项目中使用 ESB 有意义 ESB 以及像 Mule 这样的 ESB 促进者 是否提供了 PHP 和本地 LAMP 技术所缺乏的任何功能 Edit 我
  • 如何使用 selenium 和 junit 测试多个浏览器(版本)

    我刚刚发现了硒 一个很棒的工具 我计划运行 使用 selenium ide 生成的 junit4 代码 但我需要它与许多浏览器 网络驱动程序一起运行 这个用例有 junit java 模式吗 我的第一个想法是使用 RunWith Param
  • 如何在 Android 上将 ISO 8601 字符串解析为 Java 日期 [重复]

    这个问题在这里已经有答案了 我正在 Android 上创建一个与服务器通信的应用程序 该服务器给我返回了一个ISO 8601 http en wikipedia org wiki ISO 8601日期字符串 如下所示 2014 11 21
  • 如何解决Spring Data JPA中的N+1问题?

    我使用 Spring Data JPA 作为持久层 并且面临 N 1 问题 我还使用规范 API 因为我发现很难解决 N 1 问题 请帮忙 Entity public class PopulationHealth Id private in
  • 在 IntelliJ IDEA 中编辑并继续?

    使用 IntelliJ IDEA 社区版进行调试时是否可以编辑一些代码 我在选项中找不到这个功能 是的 这就是所谓的 热插拔 您可以在调试过程中编译修改后的代码 并且类文件将被替换 直到您停止调试 确保在调试器设置中启用 HotSwap 选
  • Jackson - 将值传递给 JsonDeserializer

    我有一个现有的类层次结构 如下所示 public interface Service String getId String getName public class FooTask extends AbstractTask private
  • 从 ArrayList HashMap 中获取多个随机值

    我想从 ArrayList 中获取一些特定数字的随机值 final ArrayList
  • 接受 05/05/1999 和 5/5/1999 等的日期时间解析

    有没有一种简单的方法来解析可能为 MM DD yyyy M D yyyy 或某种组合的日期 即 在一位数字的日期或月份之前 零是可选的 要手动执行此操作 可以使用 String dateFields dateString split int
  • Java:如何实现通用二叉搜索树?

    到目前为止 我一直在编写一个 Node 类 class Node private value private Node left private Node right public int getValue return value pub
  • 带句点和逗号的自定义格式数字

    有点相关这个问题 https stackoverflow com questions 4738853 java decimal format parse to return double value with specified numbe
  • 纹理映射和光照顶点着色器错误 Java OpenGL

    我正在尝试将纹理映射到 3D 立方体并尝试编写着色器以使其具有照明和纹理 我尝试过只编写纹理着色器并且它有效 我还尝试过仅将 3D 值设置为红色的照明着色器 并且该照明着色器也可以工作 但当我尝试将两者结合起来时 我遇到了问题 我在下面提供
  • Java 中使用 PBKDF2 进行密码验证

    我正在用 Java 进行基于密码的文件加密 我使用 AES 作为底层加密算法PBKDF2WithHmacSHA1使用以下代码从盐和密码组合中派生密钥 我从本网站上的另一位慷慨的海报获得 SecretKeyFactory f SecretKe
  • 从 blob 反序列化 java 对象

    首先 我很抱歉 我要问一些愚蠢的问题 我根本不懂java 也不知道我们是否可以问这样的问题 如果没有 删除我的主题 oracle中有一个存储blob的表 它是二进制的 我能够解码它 输出看起来像这样 sr com epam insure c
  • 大十进制减法

    我想减去2double值 我尝试了以下代码 double val1 2 0 double val2 1 10 System out println val1 val2 我得到的输出为 0 8999999999999999 为了获得输出0 9
  • 将任何文件读取为二进制字符串

    正如标题所示 有什么方法可以读取 Java 或任何其他语言 中给定文件 txt docx exe 等 的二进制表示形式 在java中 我知道如何按原样读取文件的内容 即 String line BufferedReader br new B
  • Hibernate 对于 Android 应用程序来说是一种杀伤力吗? [复制]

    这个问题在这里已经有答案了 我正在为我的 Android 应用程序寻找一个好的 ORM 乍一看似乎对于移动设备我更喜欢使用更简单的东西 问题是我只是在这里假设 没有真正的证据 所以我想我应该询问社区的意见 也许有人有过这样的经历 它是一个相
  • 为什么 java.io.File 没有 close 方法?

    While java io RandomAccessFile确实有一个close method java io File没有 这是为什么 文件在完成时会自动关闭吗 javadoc 的Fileclass 将该类描述为 文件和目录路径名的抽象表

随机推荐

  • 拒绝后门程序-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