`
wx1568905209
  • 浏览: 25101 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

SpringBoot 学习之RestTemplate

 
阅读更多

前言

概述

  RestTemplate 是 Spring 提供的用于访问Rest服务的客户端,RestTemplate 提供了多种便捷访问远程Http服务的方法,它简化了与 http 服务的通信方式,统一了 RESTful 的标准,封装了 http 链接, 我们只需要传入 url 及返回值类型即可。相较于之前常用的 HttpClient,RestTemplate 是一种更优雅的调用 RESTful 服务的方式。默认情况下,RestTemplate 默认依赖 jdk 的HTTP连接工具(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。

该模板类的主要切入点为以下几个方法(其根据HTTP的六个方法制定六个主要方法)

HTTPMethod RestTemplate Method 说明
Post postForLocation POST 数据到一个URL,返回新创建资源的URL
postForEntity POST 数据到一个URL,返回包含一个对象的ResponseEntity
postForObject POST 数据到一个URL,返回根据响应体匹配形成的对象
Get getForObject 发送一个HTTP GET请求,返回的请求体将映射为一个对象
getForEntity 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
Delete delete
head headForHeaders
put put
any exchange
execute 所有的get、post、delete、put、options、head、exchange方法最终调用的都是excute方法

对外开放的接口

对外开放的接口

  • [x] 在内部,RestTemplate默认使用HttpMessageConverter实例将HTTP消息转换成POJO或者从POJO转换成HTTP消息

RestTemplate是 spring 的一个 rest 客户端,在 spring-web 这个包下,spring boot的依赖如下:

<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

RestTemplate只是对其它Rest客户端的一个封装,本身并没有自己的实现。在没有第三方依赖的情况下其默认实现是HttpURLConnection(集成了URLConnection),这是JDK自带的REST客户端实现。现在来看下其它最常用的几种客户端的引入

SimpleClientHttpRequestFactory(封装URLConnection)
HttpComponentsClientHttpRequestFactory(封装HttpClient)
OkHttp3ClientHttpRequestFactory(封装OKHttp)

其切换与使用也很简单,在pom中引入相应依赖

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
</dependency>

初始化RestTemplate

 在Config中的配置:

package org.dllwh.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
	@Bean
	public RestTemplate restTemplate() {
		RestTemplate restTemplate = new RestTemplate();
		return restTemplate;
	}

	@Bean("urlConnection")
	public RestTemplate urlConnectionRestTemplate() {
		RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory());
		return restTemplate;
	}

	@Bean("httpClient")
	public RestTemplate httpClientRestTemplate() {
		RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
		return restTemplate;
	}

	@Bean("OKHttp3")
	public RestTemplate OKHttp3RestTemplate() {
		RestTemplate restTemplate = new RestTemplate(new OkHttp3ClientHttpRequestFactory());
		return restTemplate;
	}
}

 使用的时候一般都会只选择其中的一种,所以上面的几种配置任选其一。这里仅仅只是演示说明

 RestTemplate前先得做一些初始化处理,比如指定http客户端工厂类、设置超时时间、响应参数转换器等。以 HttpComponents 为例说明。

package org.dllwh.config;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class RestTemplateConfig {
	/** 建立连接的超时时间 */
	private static int	connectTimeout		= 20000;
	/** 连接不够用的等待时间 */
	private static int	requestTimeout		= 20000;
	/** 每次请求等待返回的超时时间 */
	private static int	socketTimeout		= 30000;
	/** 每个主机最大连接数 */
	private static int	defaultMaxPerRoute	= 100;
	/** 最大连接数 */
	private static int	maxTotalConnections	= 300;

	@Bean
	public RestTemplate buildRestTemplate(ClientHttpRequestFactory factory) {
		RestTemplate restTemplate = new RestTemplate(factory);
		restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
		return restTemplate;
	}

	/**
	 * @方法描述:创建HTTP客户端工厂
	 * @return
	 */
	@Bean
	public HttpComponentsClientHttpRequestFactory createFactory() {
		// httpClient连接配置
		SSLContextBuilder builder = new SSLContextBuilder();

		try {
			TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
				public boolean isTrusted(X509Certificate[] chain, String authType) {
					return true;
				}
			};

			builder.loadTrustMaterial(null, acceptingTrustStrategy);
		} catch (Exception e) {
			log.error("Pooling Connection Manager Initialisation failure because of " + e.getMessage(), e);
		}

		SSLConnectionSocketFactory socketFactory = null;
		try {
			socketFactory = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE);
		} catch (KeyManagementException | NoSuchAlgorithmException e) {
			log.error("Pooling Connection Manager Initialisation failure because of " + e.getMessage(), e);
		}

		// 注册http和https请求
		Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create()
				.register("http", PlainConnectionSocketFactory.getSocketFactory())
				.register("https", socketFactory).build();

		// 开始设置连接池
		PoolingHttpClientConnectionManager phccm = new PoolingHttpClientConnectionManager(registry);
		// 最大连接数
		phccm.setMaxTotal(maxTotalConnections);
		// 同路由并发数
		phccm.setDefaultMaxPerRoute(defaultMaxPerRoute);

		HttpClientBuilder httpClientBuilder = HttpClients.custom();
		httpClientBuilder.setSSLSocketFactory(socketFactory);
		httpClientBuilder.setConnectionManager(phccm);
		httpClientBuilder.setConnectionManagerShared(true);
		// 重试次数,默认是3次,没有开启
		httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true));
		// 保持长连接配置,需要在头添加Keep-Alive
		httpClientBuilder.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE);

		List<Header> headers = new ArrayList<>();
		headers.add(new BasicHeader("User-Agent", 
		    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36"));
		headers.add(new BasicHeader("Connection", "keep-alive"));

		httpClientBuilder.setDefaultHeaders(headers);

		CloseableHttpClient httpClient = httpClientBuilder.build();

		// httpClient连接配置,底层是配置RequestConfig
		HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();

		factory.setHttpClient(httpClient);
		// 连接超时
		factory.setConnectTimeout(connectTimeout);
		// 数据读取超时时间,即SocketTimeout
		factory.setReadTimeout(socketTimeout);
		// 连接不够用的等待时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的
		factory.setConnectionRequestTimeout(requestTimeout);
		// 缓冲请求数据,默认值是true。通过POST或者PUT大量发送数据时,建议将此属性更改为false,以免耗尽内存。
		factory.setBufferRequestBody(false);
		return factory;
	}
}

GET请求

getForEntity

getForEntity() 的返回值类型 ResponseEntity,通过源码可以看到它继承了 HttpEntity ,封装了返回的响应信息,包括 响应状态、响应头、响应体等,获取Http请求的全部信息。

<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
		throws RestClientException;

<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
		throws RestClientException;

<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;
ResponseEntity response = restTemplate.getForEntity("http://localhost:8081/server",String.class);
response.getHeaders();		//响应头
response.getStatusCode();	//响应码
response.getBody();			//响应体,即前面的result
  • [ ] 第1个参数:要调用的服务的地址
  • [ ] 第2个参数:表示希望返回的body类型
  • [ ] 第3个以及以后参数:表示请求参数
  • 可以使用map来封装请求参数,并作为getForObject的第三个参数,同时修改url如下,map中的"1"会替换url中的{1},"2"会替换url中的{2}
Map map = new HashMap();
map.put("1", "hello");
map.put("2", "world");
String result = restTemplate.getForObject("http://localhost:8081/server?param1={1}&param2={2}",
		String.class, map);
  • 也可以直接将要传递的值放到getForObject方法的参数结尾,数量不限,它会按顺序替换{1}和{2}
String result = restTemplate.getForObject("http://localhost:8081/server?param1={1}&param2={2}",
		String.class, "hello", "world");

getForObject

 getForObject 和 getForEntity 用法几乎相同,实际上是对getForEntity函数的进一步封装,返回值返回的是 响应体,省去了我们 再去 getBody()。

POST请求

postForObject

postForObject指post请求,并返回一个Object对象

String response = restTemplate.postForObject("http://localhost:8081/server?param1={1}&param2={2}",
		null, String.class, "hello", "world");
  • [ ] 第1个参数就是getForObject第1个参数。
  • [ ] 第2个参数为null,实际上是HttpEntity
  • [ ] 第3个参数就是getForObject第2个参数
  • [ ] 第4个及以后的参数就是getForObject第3个及以后的参数

postForObject除了第2个参数为null,其它地方用法和getForObject是一模一样的。但是post请求传参通常不是写在url上实现的,而是放在请求体中。此时,就需要使用第2个参数来传参,同时可省略第4个参数的url传参

Map map = new HashMap();
map.put("param1", "hello");
map.put("param2", "world");
String response = restTemplate.postForObject("http://localhost:8081/server", map, String.class);
  • [x] 注意,服务端端接收不同参数时,语法也有所不同
public String server(@RequestBody Map map,String param1,String param2)

postForEntity

<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType,
		Object... uriVariables) throws RestClientException;

<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType,
		Map<String, ?> uriVariables) throws RestClientException;

<T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType)
		throws RestClientException;

postForLocation

PUT请求

 在RestTemplate中,PUT请求可以通过put方法调用,put方法的参数和前面介绍的postForEntity方法的参数基本一致,只是put方法没有返回值而已

@RequestMapping("put")
public void put() {
    restTemplate.put("http://http://localhost:8081/server/put/?userName={1}", '独泪了无痕');
}

DELETE请求

 delete请求我们可以通过delete方法调用来实现

@RequestMapping("delete")
public void delete() {
    restTemplate.delete("http://localhost:8081/server/delete/{1}", 100);
}

Exchange请求

 exchange()方法跟上面的getForObject()、getForEntity()、postForObject()、postForEntity()等方法不同之处在于它可以指定请求的HTTP类型。

需要注意的一点是对于返回结果为204 no content,这种没有返回值的请求,RestTemplate会抛错,有需要的话可以使用httpClient的fluent

Excute请求

excute() 的用法与 exchange() 大同小异了,它同样可以指定不同的 HttpMethod,不同的是它返回的对象是响应体所映射成的对象 ,而不是 ResponseEntity 。

Excute方法的调用过程

转载于:https://my.oschina.net/u/1030471/blog/3006333

分享到:
评论

相关推荐

    SpringBoot系列之RestTemplate使用示例

    SpringBoot系列之RestTemplate使用示例,博主之前经常对接一些接口,所以发现写一些http请求比较麻烦,学习springboot的过程知道可以用 RestTemplate来做http请求,RestTemplate 是 Spring Framework 框架封装的基于...

    Springboot集成restTemplate过程详解

    主要介绍了Springboot集成restTemplate过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    SpringBoot代码示例,结合Swagger、MyBatis Plus、RestTemplate等技术,是学习微服务的基础demo示例

    该示例结合Swagger生成在线API,MyBatis Plus快速分页查询、RestTemplate实现远程访问服务端接口等基于SpringBoot框架的demo示例,对大家学习SpringCloud打下良好基础

    springboot的测试,适合小白前期学习springboot

    在学习过程中,结合具体的代码示例和实际操作,将会使理解更加深刻。遗憾的是,文件名"girl"并没有直接关联到SpringBoot测试的知识点,但可能指的是一个示例项目或者测试用例的名字。在实践中,这样的命名可以帮助...

    springboot038基于SpringBoot的网上租赁系统设计与实现.zip

    总的来说,"springboot038"项目展示了如何利用SpringBoot框架构建一个完整的网上租赁系统,涵盖了从用户交互到后台管理的多个层面,对于理解和学习SpringBoot的实际应用具有很高的参考价值。通过深入研究这个项目,...

    基于Springboot的网上点餐系统(有报告) Javaee项目,springboot项目

    Springboot可以通过RestTemplate或WebClient来调用这些API,实现在线支付。此外,为了保证交易安全,系统还需要处理支付状态的同步和异步回调,这部分通常需要设计合理的消息队列和监听机制,例如使用RabbitMQ或...

    SpringBoot2.2.1整合项目.zip

    HTTP通信则常常涉及到与外部服务的交互,SpringBoot的RestTemplate或者WebClient可以方便地发送HTTP请求。此外,自定义拦截器或者Filter可以实现请求和响应的拦截,进行统一的日志记录或权限验证。 最后,字符串...

    springboot+mybatis工作中出现的问题汇总和学习新知识的总结.docx

    在SpringBoot和Mybatis结合的开发环境中,遇到的问题和学习的新知识主要集中在前端与后端的数据交互、控制器层的处理以及API调用等方面。以下是对这些知识点的详细说明: 1. **前端Ajax传参**:前端通过Ajax进行...

    springboot029基于springboot的网上购物商城系统研发毕业源码案例设计.zip

    这通常涉及到HTTP请求的发送和解析,SpringBoot的RestTemplate或者WebClient可提供支持。 6. **前端界面**:虽然SpringBoot主要关注后端,但该项目可能包含Vue、React或Angular等前端框架的代码,用于构建用户友好...

    springboot +mybatis+dubbo案例

    通过此案例,你可以学习到如何在SpringBoot中集成MyBatis和Dubbo,理解微服务架构的设计思想,以及如何在实际开发中运用这些技术解决复杂的问题。同时,你还可以掌握如何管理和调试分布式系统,提升自己的开发和运维...

    SpringBoot集成ocr功能demo

    通过这个SpringBoot集成OCR功能的示例项目,开发者可以学习到如何将OCR技术融入到Spring Boot应用中,提升应用的智能化程度,从而提高工作效率和用户体验。同时,这也是一个了解和实践Java Web开发、RESTful API调用...

    基于springboot的结合疫情情况的婚恋系统源码.zip

    这可能需要调用第三方API获取疫情数据,使用SpringBoot的RestTemplate或者WebClient来实现API的调用。 4. 通信模块:实现用户之间的消息传递,可以采用WebSocket技术,SpringBoot提供了对WebSocket的支持。 5. ...

    基于springboot的社区团购系统源码.zip

    《基于SpringBoot的社区团购系统源码解析》 在当今数字化时代,社区团购作为一种...通过深入学习和分析源码,开发者不仅能掌握SpringBoot的核心特性,还能了解社区团购业务的运作流程,为今后的项目开发积累宝贵经验。

    springboot整合eureka源代码,学习资料

    SpringBoot整合Eureka是构建微服务架构中的关键一环,Spring Boot简化了Spring应用程序的启动和配置,而Eureka则是Netflix开源的微服务组件,主要负责服务注册与发现。本学习资料聚焦于如何将这两者结合,以实现高效...

    基于springboot数字商城管理子系统-源码

    《基于SpringBoot的数字商城管理子系统源码...通过阅读和学习这个源码,开发者不仅可以了解SpringBoot的实践应用,还能学习到如何设计和实现一个完整的电商后台系统。对于提升自己的技术能力和项目经验具有很大的帮助。

    基于SpringBoot+SpringCloud的微服务大型在线学习平台实现【服务端源码+数据库】.zip

    基于SpringBoot+SpringCloud的微服务大型在线学习平台实现【服务端源码+数据库】.zip 项目介绍 学成在线就是一个在线学习平台,类似慕课网以及腾讯学堂,是专门针对IT行业进行在线学习的平台。 学成在线采用B2B2C的...

    基于springboot的智能点餐平台源码.zip

    总而言之,这个压缩包提供了一个完整的、基于SpringBoot的点餐平台实现,对于学习SpringBoot开发、理解微服务架构以及Java Web开发流程都有很高的参考价值。通过研究这个源码,开发者可以深入理解SpringBoot的原理,...

    springboot做的天气查看及jps定位

    在本项目中,"springboot做的天气查看及jps定位"是一个使用Spring Boot框架构建的应用,它整合了天气查询功能并结合了Java进程状态检查工具(JPS)。这个应用展示了Spring Boot如何优雅地将多种服务集成在一起,为...

    SpringBoot酒店管理系统.zip

    总之,"SpringBoot酒店管理系统"项目提供了一个实践SpringBoot技术的绝佳平台,通过对这个系统的分析和学习,开发者不仅可以掌握SpringBoot的核心技术,还能了解到如何将这些技术应用于实际的业务场景,提升自己的...

Global site tag (gtag.js) - Google Analytics