RestTemplate的详解

引言
在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)。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值