好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

springboot集成RestTemplate及常见的用法说明

一、背景介绍 

在微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate。

这里介绍的是RestTemplate。RestTemplate底层用还是HttpClient,对其做了封装,使用起来更简单。

1、什么是RestTemplate?

RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用java.net包下的实现创建HTTP 请求,可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式。

ClientHttpRequestFactory接口主要提供了两种实现方式

1、一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接。

2、一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。

其实spring并没有真正的去实现底层的http请求(3次握手),而是集成了别的http请求,spring只是在原有的各种http请求进行了规范标准,让开发者更加简单易用,底层默认用的是jdk的http请求。

2、RestTemplate的优缺点

优点:连接池、超时时间设置、支持异步、请求和响应的编解码 缺点:依赖别的spring版块、参数传递不灵活

RestTemplate默认是使用SimpleClientHttpRequestFactory,内部是调用jdk的HttpConnection,默认超时为-1

?

1

2

3

4

@Autowired

RestTemplate simpleRestTemplate;

@Autowired

RestTemplate restTemplate;

二、配置RestTemplate

1、引入依赖

?

1

2

3

4

5

6

7

8

9

< dependency >

     < groupId >org.apache.httpcomponents</ groupId >

     < artifactId >httpclient</ artifactId >

     < version >4.5.6</ version >

</ dependency >

< dependency >

     < groupId >org.springframework.boot</ groupId >

     < artifactId >spring-boot-starter-web</ artifactId >

</ dependency >

2、连接池配置

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#最大连接数

http.maxTotal: 100

#并发数

http.defaultMaxPerRoute: 20

#创建连接的最长时间

http.connectTimeout: 1000

#从连接池中获取到连接的最长时间

http.connectionRequestTimeout: 500

#数据传输的最长时间

http.socketTimeout: 10000

#提交请求前测试连接是否可用

http.staleConnectionCheckEnabled: true

#可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立

http.validateAfterInactivity: 3000000

3、初始化连接池

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

package com.example.demo.config;

import org.apache.http.client.HttpClient;

import org.apache.http.client.config.RequestConfig;

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.SSLConnectionSocketFactory;

import org.apache.http.impl.client.HttpClientBuilder;

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import org.springframework.beans.factory.annotation.Value;

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.RestTemplate;

 

@Configuration

public class RestTemplateConfig {

     @Value ( "${http.maxTotal}" )

     private Integer maxTotal;

 

     @Value ( "${http.defaultMaxPerRoute}" )

     private Integer defaultMaxPerRoute;

 

     @Value ( "${http.connectTimeout}" )

     private Integer connectTimeout;

 

     @Value ( "${http.connectionRequestTimeout}" )

     private Integer connectionRequestTimeout;

 

     @Value ( "${http.socketTimeout}" )

     private Integer socketTimeout;

 

     @Value ( "${http.staleConnectionCheckEnabled}" )

     private boolean staleConnectionCheckEnabled;

 

     @Value ( "${http.validateAfterInactivity}" )

     private Integer validateAfterInactivity;

 

     @Bean

     public RestTemplate restTemplate() {

         return new RestTemplate(httpRequestFactory());

     }

 

     @Bean

     public ClientHttpRequestFactory httpRequestFactory() {

         return new HttpComponentsClientHttpRequestFactory(httpClient());

     }

 

     @Bean

     public HttpClient httpClient() {

         Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()

                 .register( "http" , PlainConnectionSocketFactory.getSocketFactory())

                 .register( "https" , SSLConnectionSocketFactory.getSocketFactory())

                 .build();

         PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);

         connectionManager.setMaxTotal(maxTotal); // 最大连接数

         connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);    //单个路由最大连接数

         connectionManager.setValidateAfterInactivity(validateAfterInactivity); // 最大空间时间

         RequestConfig requestConfig = RequestConfig.custom()

                 .setSocketTimeout(socketTimeout)        //服务器返回数据(response)的时间,超过抛出read timeout

                 .setConnectTimeout(connectTimeout)      //连接上服务器(握手成功)的时间,超出抛出connect timeout

                 .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled) // 提交前检测是否可用

                 .setConnectionRequestTimeout(connectionRequestTimeout) //从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool

                 .build();

         return HttpClientBuilder.create()

                 .setDefaultRequestConfig(requestConfig)

                 .setConnectionManager(connectionManager)

                 .build();

     }

}

4、使用示例

RestTemplate是对HttpCilent的封装,所以,依HttpCilent然可以继续使用HttpCilent。看下两者的区别

HttpCilent:

?

1

2

3

4

5

6

7

8

@RequestMapping ( "/testHttpClient" )

@ResponseBody

public Object getUser(String msg) throws IOException {

     CloseableHttpClient closeableHttpClient = HttpClients.createDefault();

     HttpGet get = new HttpGet( "http://192.168.1.100:8080/User/getAllUser" );

     CloseableHttpResponse response = closeableHttpClient.execute(get);

     return EntityUtils.toString(response.getEntity(), "utf-8" );

}

RestTemplate:

?

1

2

3

4

5

6

@RequestMapping ( "/testRestTemplate" )

@ResponseBody

public Object testRestTemplate() throws IOException {

     ResponseEntity result = restTemplate.getForEntity( "http://192.168.1.100:8080/User/getAllUser" ,ResponseEntity. class ;

     return result.getBody();

}

RestTemplate更简洁了。

三、RestTemplate常用方法

1、getForEntity

getForEntity方法的返回值是一个ResponseEntity<T>,ResponseEntity<T>是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等。比如下面一个例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

@RequestMapping ( "/sayhello" )

public String sayHello() {

     ResponseEntity<String> responseEntity = restTemplate.getForEntity( "http://HELLO-SERVICE/sayhello?name={1}" , String. class , "张三" );

     return responseEntity.getBody();

}

@RequestMapping ( "/sayhello2" )

public String sayHello2() {

     Map<String, String> map = new HashMap<>();

     map.put( "name" , "李四" );

     ResponseEntity<String> responseEntity = restTemplate.getForEntity( "http://HELLO-SERVICE/sayhello?name={name}" , String. class , map);

     return responseEntity.getBody();

}

2、getForObject

getForObject函数实际上是对getForEntity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时

可以使用getForObject,举一个简单的例子,如下:

?

1

2

3

4

5

@RequestMapping ( "/book2" )

public Book book2() {

     Book book = restTemplate.getForObject( "http://HELLO-SERVICE/getbook1" , Book. class );

     return book;

}

3、postForEntity

?

1

2

3

4

5

6

7

@RequestMapping ( "/book3" )

public Book book3() {

     Book book = new Book();

     book.setName( "红楼梦" );

     ResponseEntity<Book> responseEntity = restTemplate.postForEntity( "http://HELLO-SERVICE/getbook2" , book, Book. class );

     return responseEntity.getBody();

}

方法的第一参数表示要调用的服务的地址 方法的第二个参数表示上传的参数 方法的第三个参数表示返回的消息体的数据类型

4、postForObject

如果你只关注,返回的消息体,可以直接使用postForObject。用法和getForObject一致。

5、postForLocation

postForLocation也是提交新资源,提交成功之后,返回新资源的URI,postForLocation的参数和前面两种的参数基本一致,只不过该方法的返回值为Uri,这个只需要服务提供者返回一个Uri即可,该Uri表示新资源的位置。

6、PUT请求

在RestTemplate中,PUT请求可以通过put方法调用,put方法的参数和前面介绍的postForEntity方法的参数基本一致,只是put方法没有返回值而已。举一个简单的例子,如下:

?

1

2

3

4

5

6

@RequestMapping ( "/put" )

public void put() {

     Book book = new Book();

     book.setName( "红楼梦" );

     restTemplate.put( "http://HELLO-SERVICE/getbook3/{1}" , book, 99 );

}

7、DELETE请求

?

1

2

3

4

5

delete请求我们可以通过delete方法调用来实现,如下例子:

@RequestMapping ( "/delete" )

public void delete() {

     restTemplate.delete( "http://HELLO-SERVICE/getbook4/{1}" , 100 );

}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/Farrell_zeng/article/details/107086054

查看更多关于springboot集成RestTemplate及常见的用法说明的详细内容...

  阅读:16次