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的六个方法制定六个主要方法)

HTTPMethodRestTemplate Method说明
PostpostForLocationPOST 数据到一个URL,返回新创建资源的URL
 postForEntityPOST 数据到一个URL,返回包含一个对象的ResponseEntity
 postForObjectPOST 数据到一个URL,返回根据响应体匹配形成的对象
GetgetForObject发送一个HTTP GET请求,返回的请求体将映射为一个对象
 getForEntity发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
Deletedelete 
headheadForHeaders 
putput 
anyexchange 
 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方法的调用过程

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot使用RestTemplate,可以通过以下步骤进行配置和使用。 首先,需要在Spring Boot应用程序的配置类中创建一个RestTemplate的实例,并将其声明为一个Bean。可以使用注解`@Bean`来实现这一点。例如,在配置类中添加以下代码: ```java @Bean public RestTemplate restTemplate() { return new RestTemplate(); } ``` 然后,可以在需要使用RestTemplate的地方通过依赖注入的方式引入RestTemplate实例。可以使用`@Autowired`注解来实现依赖注入。例如: ```java @Autowired private RestTemplate restTemplate; ``` 接下来,可以使用RestTemplate的各种方法发送HTTP请求。根据请求的类型和参数的传递方式,可以选择使用不同的方法,比如`getForObject()`、`postForObject()`等。具体的使用方法可以参考中的参考资料。 总结起来,使用RestTemplate的步骤可以概括为以下几点: 1. 在配置类中创建RestTemplate的实例,并将其声明为一个Bean。 2. 在需要使用RestTemplate的地方通过依赖注入的方式引入RestTemplate实例。 3. 使用RestTemplate的方法发送HTTP请求,根据请求类型和参数的传递方式选择合适的方法。 以上就是使用RestTemplate的简单介绍和使用步骤。希望能对您有所帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [SpringBoot使用RestTemplate](https://blog.csdn.net/weixin_42408447/article/details/117560736)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独泪了无痕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值