Spring之RestTemplate介绍
RestTemplate是Spring Web模块提供的一个基于Rest规范提供Http请求的工具。应用中如果需要访问第三方提供的Rest接口,使用RestTemplate操作将非常方便。RestTemplate中提供了一系列的getXXX、postXXX、putXXX、deleteXXX等方法,以供发起对应的Rest规范请求,以及更通用的exchange和execute系列方法。方法详情可以参考对应的API文档或源码。
发起GET请求
通过getForObject
可以发起GET请求,下面的代码中就展示了通过getForObject
发起GET请求,第二个参数指定返回类型,指定String则表示以文本形式进行返回。
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("https://www.so.com/s?ie=utf-8&q=中国", String.class);
System.out.println(response);
使用路径变量
URI中还可以使用路径变量。下面的代码中URI中就包含了一个路径变量word
,路径变量可以作为最后一个参数传递,RestTemplate将自动进行替换。所以最终请求的URL是https://www.so.com/s?ie=utf-8&q=ABC
。
RestTemplate restTemplate = new RestTemplate();
String word = "ABC";
String response = restTemplate.getForObject("https://www.so.com/s?ie=utf-8&q={word}", String.class, word);
System.out.println(response);
当路径变量有多个时,可以按照顺序在最后依次传递。下面的代码中就定义了两个路径变量,charset和word,然后传递路径变量时,第一个参数值utf-8
将传递给定义的第一个路径变量charset,第二个参数值ABC
将传递给定义的第二个路径变量word。所以最终请求的URL将是https://www.so.com/s?ie=utf-8&q=ABC
。
RestTemplate restTemplate = new RestTemplate();
String uri = "https://www.so.com/s?ie={charset}&q={word}";
String response = restTemplate.getForObject(uri, String.class, "utf-8", "ABC");
System.out.println(response);
路径变量也可以通过Map传递,这样将更加精确,尤其是在有路径变量相同的情况下。下面的代码中就展示了如何通过Map传递路径变量。
RestTemplate restTemplate = new RestTemplate();
String uri = "https://www.so.com/s?ie={charset}&q={word}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("charset", "utf-8");
uriVariables.put("word", "ABC");
String response = restTemplate.getForObject(uri, String.class, uriVariables);
System.out.println(response);
响应内容使用ResponseEntity接收
响应内容也可以通过ResponseEntity接收,这样可以访问到响应的Http状态码和头信息。
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate.getForEntity("https://www.so.com/s?ie=utf-8&q=ABC", String.class);
if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
System.out.println("Get Success");
}
System.out.println("Headers: ");
HttpHeaders headers = responseEntity.getHeaders();
headers.forEach((name, values) -> {
System.out.println(name + " = " + values);
});
if (responseEntity.hasBody()) {
System.out.println("response: ");
System.out.println(responseEntity.getBody());
}
返回复杂对象
RestTemplate的请求响应对象不仅仅可以是String,也可以是一个复杂对象。发起请求的过程中的请求内容和响应内容都会经过org.springframework.http.converter.HttpMessageConverter
进行处理,这跟Spring MVC中是一样的。
RestTemplate restTemplate = new RestTemplate();
User user = restTemplate.getForObject("http://localhost:8081/user/1", User.class);
System.out.println(user);
RestTemplate中默认会添加如下HttpMessageConverter,其中if语句块包含的HttpMessageConverter将在Classpath下拥有指定的Class时才会添加。从下面的代码可以看出,如果需要请求的Object能够自动转换为JSON对象进行请求或者响应的JSON对象能够自动转换为Object,可以加入Jackson依赖,这样将自动加入MappingJackson2HttpMessageConverter。
public RestTemplate() {
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter(false));
this.messageConverters.add(new SourceHttpMessageConverter<>());
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
this.messageConverters.add(new AtomFeedHttpMessageConverter());
this.messageConverters.add(new RssChannelHttpMessageConverter());
}
if (jackson2XmlPresent) {
this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
}
else if (jaxb2Present) {
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
if (jackson2Present) {
this.messageConverters.add(new MappingJackson2HttpMessageConverter());
}
else if (gsonPresent) {
this.messageConverters.add(new GsonHttpMessageConverter());
}
else if (jsonbPresent) {
this.messageConverters.add(new JsonbHttpMessageConverter());
}
if (jackson2SmilePresent) {
this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
}
if (jackson2CborPresent) {
this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
}
}
添加自己的HttpMessageConverter
RestTemplate自带的HttpMessageConverter可能并不能完全满足你的需求。我们可以往HttpMessageConverter队列中添加自己的HttpMessageConverter。比如如果JSON处理你更喜欢使用Alibaba Fastjson,则可以添加FastJsonHttpMessageConverter到HttpMessageConverter列表,如果列表中已经拥有了可以处理JSON的HttpMessageConverter,则需要把它添加到原来处理JSON的HttpMessageConverter的前面。
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(0, new FastJsonHttpMessageConverter());
User user = restTemplate.getForObject("http://localhost:8081/user/1", User.class);
System.out.println(user);
添加HttpMessageConverter到HttpMessageConverter列表可以通过获取已有的列表再添加,也可以通过
setMessageConverters
方法指定,前者用于追加,后者将进行完整的替换。
已有的处理String的StringHttpMessageConverter默认使用的字符集是ISO-8859-1,这对使用中文的我们来说可能不合适,所以可以添加一个基于UTF-8字符集的StringHttpMessageConverter到现有的HttpMessageConverter列表中,然后需要保证在已有的StringHttpMessageConverter的前面。
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
String request = "你好";
Class<String> responseType = String.class;
String result = restTemplate.postForObject("http://localhost:8081/hello/string", request, responseType);
System.out.println(result);
请求内容使用HttpEntity对象
在请求时如果需要指定Header信息,则可以将请求内容包装为一个HttpEntity对象。下面的代码中就传递了两个Header,但是没有传递其它body内容,如果需要传递body也是可以的,HttpBody拥有对应的重载的构造方法。
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("abc", "123");//自定义Header
headers.add("Content-Type", "text/plain");//标准Header
HttpEntity<Void> httpEntity = new HttpEntity<>(headers);
Class<String> responseType = String.class;
String result = restTemplate.postForObject("http://localhost:8081/hello/header", httpEntity, responseType);
System.out.println(result);
RestTemplate的没有提供传递HttpEntity对象的getXXX方法,如果在进行GET请求时需要传递HttpEntity对象怎么办呢?这个时候可以使用万能的exchange方法。下面的代码使用了exchange方法进行了GET请求,同时通过HttpEntity定义了一些头信息。
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("abc", "123");//自定义Header
headers.add("Content-Type", "text/plain");//标准Header
HttpEntity<Void> httpEntity = new HttpEntity<>(headers);
Class<String> responseType = String.class;
ResponseEntity<String> responseEntity = restTemplate.exchange("http://localhost:8081/hello/header", HttpMethod.GET, httpEntity, responseType);
System.out.println(responseEntity.getBody());
使用Apache HttpComponents实现
RestTemplate默认使用的是基于JDK的Http请求实现,RestTemplate中发起Http请求的操作被封装到了ClientHttpRequestFactory接口,默认使用的是org.springframework.http.client.SimpleClientHttpRequestFactory
实现。Spring同样提供了基于Apache HttpComponents的实现类,org.springframework.http.client.HttpComponentsClientHttpRequestFactory
。其它实现类可以参考API文档。使用Apache HttpComponents实现需要加入相应依赖。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
可以通过RestTemplate的setRequestFactory()
指定需要使用的ClientHttpRequestFactory。使用Apache HttpComponents的实现的好处是可以利用其内部的连接池实现。下面的代码展示了如何使用基于Apache HttpComponents的实现进行编程。
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10*1000).setConnectionRequestTimeout(30*1000).build();
HttpClient httpClient = HttpClientBuilder.create().setMaxConnPerRoute(20).setMaxConnTotal(50).setDefaultRequestConfig(requestConfig).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(requestFactory);
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost:8081/hello/json", String.class);
System.out.println(responseEntity);
如果需要在客户端进行异步的Http请求,还可以使用AsyncRestTemplate。不过它从Spring5开始已经废弃了。
(注:本文基于Spring4.1.0所写)
相关推荐
SpringCloud提供了`@LoadBalanced`注解,可以配合`RestTemplate`或`Feign`实现负载均衡的远程调用。例如,对于`RestTemplate`,只需如下配置: ```java @Autowired private LoadBalancerClient loadBalancer; @...
首先,让我们了解Spring Cloud的核心组件之一——Nacos。Nacos是一个动态服务发现、配置管理和服务管理平台,它可以作为微服务架构中的服务中心,帮助服务实例注册与发现。在使用`RestTemplate`调用服务之前,我们...
Spring Cloud为了解决这个问题,提供了一种简单易用的工具——RestTemplate。本示例将详细解析如何利用RestTemplate进行服务间的调用,帮助开发者理解并实践相关知识。 首先,我们要知道什么是RestTemplate。...
在服务发现方面,你可以通过 Spring Cloud 的 RestTemplate 或者 Feign 客户端来实现。例如,使用 RestTemplate 获取服务实例列表: ```java @Autowired private DiscoveryClient discoveryClient; public List...
6. **支付集成**:可能与第三方支付平台(如支付宝或微信支付)进行集成,Spring的RestTemplate或WebClient可以用来发送和接收API请求。 在"chapter8"这个文件名中,虽然没有具体说明,但可能表示项目的某个章节或...
首先,让我们了解SpringCloud的核心组件之一——Eureka。Eureka是SpringCloud的服务注册与发现组件,它允许各个微服务实例向中心注册,并且提供服务发现功能。在集成Python服务时,我们需要在Python端实现一个Eureka...
Spring框架提供了一个强大的工具——`RestTemplate`,它使得调用RESTful API变得非常方便。本篇文章将详细讲解如何利用Spring的`RestTemplate`调用腾讯接口,并处理返回的`Entity`对象,同时还会涉及到FastJson这个...
在Spring Cloud项目中,pom.xml会包含Spring Cloud的父POM,以及Eureka Server、服务提供者和服务消费者所需的依赖,如`spring-cloud-starter-netflix-eureka-client`、`spring-cloud-starter-netflix-eureka-server...
Spring Boot提供了一个强大的工具——RestTemplate,用于发起HTTP请求。RestTemplate允许你发送GET、POST等HTTP方法请求,并处理响应。此外,Spring Web模块还引入了WebClient,这是一个反应式HTTP客户端,适用于...
本篇文章将深入探讨如何将SpringCloud与Nacos进行有效整合,通过具体的项目实例——"springcloud-nacos-demo",来解析这一过程的关键知识点。 一、SpringCloud简介 SpringCloud是基于Spring Boot实现的云应用开发...
#### 六、分布式配置中心——Spring Cloud Config Spring Cloud Config 为微服务架构中的应用提供了一种集中式的外部配置管理方案。通过 Spring Cloud Config 可以将应用的配置信息统一存储在 Git 仓库或其他版本...
总结,本压缩包“SpringCloud基础入门代码”涵盖了Spring Cloud的核心组件——Eureka服务注册与发现,以及服务提供者和消费者的基本实现,包括Template和Feign两种调用方式。对于初学者来说,这是一个很好的起点,...
SpringBoot提供了一个强大的Web客户端——RestTemplate,用于调用外部API。通过它,我们可以方便地实现与第三方支付平台的对接,处理支付的异步回调等复杂逻辑。 此外,为了保证系统的高可用性和容错性,SpringBoot...
《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...
首先,我们需要了解Spring Cloud的核心组件之一——Eureka。Eureka是一个基于REST的服务,用于服务注册与发现。在Spring Cloud应用中,每个服务实例都会向Eureka Server注册自身的信息,包括服务名、IP地址、端口等...
1. 服务发现:Ribbon与Spring Cloud的另一个组件——Eureka配合,从Eureka服务器获取服务注册列表。这些服务实例构成了Ribbon的服务器池。 2. 负载均衡策略:Ribbon内置了多种负载均衡策略,如轮询(RoundRobinRule...
在这个案例中,我们专注于SpringCloud的核心组件之一——Eureka,它是服务发现的重要工具。服务发现允许微服务之间找到并互相通信,使得系统具有更好的可扩展性和解耦性。 Eureka是Netflix开发的一个基于REST的服务...
《Spring Rest客户端示例详解——基于Spring Framework 5的实践指南》 在现代Web开发中,RESTful API已经成为服务间通信的重要方式。Spring Framework 5为开发者提供了强大的工具来构建和消费REST服务。本篇文章将...
在本教程中,我们将深入探讨Spring Cloud的核心组件之一——Eureka,它是微服务架构中的服务发现工具。Eureka是Netflix开发的一个组件,主要用于实现服务的注册与发现,它使得服务提供者可以将自己的服务注册到...