`
234390216
  • 浏览: 10238494 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:462879
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1775972
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1398730
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:395156
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:680166
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:531135
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1184996
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:468780
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:151484
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:68337
社区版块
存档分类
最新评论

Spring(30)——RestTemplate介绍

阅读更多

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所写)

0
0
分享到:
评论
2 楼 234390216 2018-07-26  
thaIm 写道
不知道RestTemplate 默认的链接数、超时时间是多少?

基于JDK的应该是无限制。
基于HttpComponents的默认最大连接数是20个,单个主机最多两个。超时时间无限制。
这些默认的很多时候文档上没有说,只能参考源码得到答案。有API可以指定的时候最好是根据实际情况进行指定,不要依赖于默认的。
1 楼 thaIm 2018-07-26  
不知道RestTemplate 默认的链接数、超时时间是多少?

相关推荐

    SpringCloud——Zookeeper(注册中心)

    SpringCloud提供了`@LoadBalanced`注解,可以配合`RestTemplate`或`Feign`实现负载均衡的远程调用。例如,对于`RestTemplate`,只需如下配置: ```java @Autowired private LoadBalancerClient loadBalancer; @...

    SpringCloud简单使用RestTemplate调用对方的服务

    首先,让我们了解Spring Cloud的核心组件之一——Nacos。Nacos是一个动态服务发现、配置管理和服务管理平台,它可以作为微服务架构中的服务中心,帮助服务实例注册与发现。在使用`RestTemplate`调用服务之前,我们...

    RestTemplate实现服务间调用demo案例

    Spring Cloud为了解决这个问题,提供了一种简单易用的工具——RestTemplate。本示例将详细解析如何利用RestTemplate进行服务间的调用,帮助开发者理解并实践相关知识。 首先,我们要知道什么是RestTemplate。...

    spring-cloud-eureka 服务注册及发现实例

    在服务发现方面,你可以通过 Spring Cloud 的 RestTemplate 或者 Feign 客户端来实现。例如,使用 RestTemplate 获取服务实例列表: ```java @Autowired private DiscoveryClient discoveryClient; public List...

    spring实现的网上书店

    6. **支付集成**:可能与第三方支付平台(如支付宝或微信支付)进行集成,Spring的RestTemplate或WebClient可以用来发送和接收API请求。 在"chapter8"这个文件名中,虽然没有具体说明,但可能表示项目的某个章节或...

    SpringCloud集成Python服务

    首先,让我们了解SpringCloud的核心组件之一——Eureka。Eureka是SpringCloud的服务注册与发现组件,它允许各个微服务实例向中心注册,并且提供服务发现功能。在集成Python服务时,我们需要在Python端实现一个Eureka...

    使用spring restTemplete 调用腾讯接口返回Entity

    Spring框架提供了一个强大的工具——`RestTemplate`,它使得调用RESTful API变得非常方便。本篇文章将详细讲解如何利用Spring的`RestTemplate`调用腾讯接口,并处理返回的`Entity`对象,同时还会涉及到FastJson这个...

    spring cloud eureka微服务之——服务注册发现、服务消费者,服务提供者简单实例

    在Spring Cloud项目中,pom.xml会包含Spring Cloud的父POM,以及Eureka Server、服务提供者和服务消费者所需的依赖,如`spring-cloud-starter-netflix-eureka-client`、`spring-cloud-starter-netflix-eureka-server...

    sxyServer.zip

    Spring Boot提供了一个强大的工具——RestTemplate,用于发起HTTP请求。RestTemplate允许你发送GET、POST等HTTP方法请求,并处理响应。此外,Spring Web模块还引入了WebClient,这是一个反应式HTTP客户端,适用于...

    springcloud-nacos-demo.zip

    本篇文章将深入探讨如何将SpringCloud与Nacos进行有效整合,通过具体的项目实例——"springcloud-nacos-demo",来解析这一过程的关键知识点。 一、SpringCloud简介 SpringCloud是基于Spring Boot实现的云应用开发...

    SpringCloud教程

    #### 六、分布式配置中心——Spring Cloud Config Spring Cloud Config 为微服务架构中的应用提供了一种集中式的外部配置管理方案。通过 Spring Cloud Config 可以将应用的配置信息统一存储在 Git 仓库或其他版本...

    springCloud入门基本代码(基础篇)

    总结,本压缩包“SpringCloud基础入门代码”涵盖了Spring Cloud的核心组件——Eureka服务注册与发现,以及服务提供者和消费者的基本实现,包括Template和Feign两种调用方式。对于初学者来说,这是一个很好的起点,...

    292064246487489springboot大学社团管理系统3rj9k.zip

    SpringBoot提供了一个强大的Web客户端——RestTemplate,用于调用外部API。通过它,我们可以方便地实现与第三方支付平台的对接,处理支付的异步回调等复杂逻辑。 此外,为了保证系统的高可用性和容错性,SpringBoot...

    Spring.3.x企业应用开发实战(完整版).part2

     《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...

    Spring cloud实现服务注册及发现

    首先,我们需要了解Spring Cloud的核心组件之一——Eureka。Eureka是一个基于REST的服务,用于服务注册与发现。在Spring Cloud应用中,每个服务实例都会向Eureka Server注册自身的信息,包括服务名、IP地址、端口等...

    spring-cloud-example-ribbon

    1. 服务发现:Ribbon与Spring Cloud的另一个组件——Eureka配合,从Eureka服务器获取服务注册列表。这些服务实例构成了Ribbon的服务器池。 2. 负载均衡策略:Ribbon内置了多种负载均衡策略,如轮询(RoundRobinRule...

    SpringCloud案例(仅集成了Eureka)

    在这个案例中,我们专注于SpringCloud的核心组件之一——Eureka,它是服务发现的重要工具。服务发现允许微服务之间找到并互相通信,使得系统具有更好的可扩展性和解耦性。 Eureka是Netflix开发的一个基于REST的服务...

    spring-rest-client-examples:Spring Rest客户端示例

    《Spring Rest客户端示例详解——基于Spring Framework 5的实践指南》 在现代Web开发中,RESTful API已经成为服务间通信的重要方式。Spring Framework 5为开发者提供了强大的工具来构建和消费REST服务。本篇文章将...

    Spring cloud 理论+实践+解析 手摸手带你一起搭建(二 Eureka服务注册中心)例程

    在本教程中,我们将深入探讨Spring Cloud的核心组件之一——Eureka,它是微服务架构中的服务发现工具。Eureka是Netflix开发的一个组件,主要用于实现服务的注册与发现,它使得服务提供者可以将自己的服务注册到...

Global site tag (gtag.js) - Google Analytics