springboot Integration with RestTemplate and Common Usage Instructions
- 2021-12-05 06:13:11
- OfStack
1. Background introduction
Microservices expose their own services in the form of HTTP interfaces, so HTTP clients must be used when calling remote services. We can use JDK native URLConnection, Apache Http Client, Netty asynchronous ES24Client, Spring RestTemplate.
This is RestTemplate. The bottom layer of RestTemplate is still HttpClient, which is encapsulated and simpler to use.
1. What is RestTemplate?
RestTemplate is a client provided by Spring for accessing Rest services, and RestTemplate provides a variety of convenient methods for accessing remote Http services, which can greatly improve the writing efficiency of clients.
The default constructor of RestTemplate is called, and the RestTemplate object creates an HTTP request at the bottom using the implementation under the java. net package, and you can specify different HTTP request methods by using ClientHttpRequestFactory.
ClientHttpRequestFactory interface mainly provides two implementation modes
1. One is SimpleClientHttpRequestFactory, which uses the method provided by J2SE (that is, the method provided by java. net package) to create the underlying Http request connection.
2. One way is to use HttpComponentsClientHttpRequestFactory. The bottom layer uses HttpClient to access remote Http services, and HttpClient can configure connection pools and certificates.
In fact, spring does not really realize the underlying http request (3 handshakes), but integrates other http requests. spring only standardizes various original http requests, making developers simpler and easier to use. The underlying default is http request of jdk.
2. Advantages and disadvantages of RestTemplate
Advantages: Connection pooling, timeout setting, support for asynchronous, request and response codec Disadvantages: Dependence on other spring section, parameter transfer is inflexibleRestTemplate uses SimpleClientHttpRequestFactory by default, and HttpConnection calls jdk internally. The default timeout is-1
@Autowired
RestTemplate simpleRestTemplate;
@Autowired
RestTemplate restTemplate;
2. Configure RestTemplate
1. Introducing dependencies
<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. Connection pool configuration
# Maximum number of connections
http.maxTotal: 100
# Concurrent number
http.defaultMaxPerRoute: 20
# Maximum time to create a connection
http.connectTimeout: 1000
# Maximum time to get a connection from the connection pool
http.connectionRequestTimeout: 500
# Maximum time for data transmission
http.socketTimeout: 10000
# Test whether the connection is available before submitting the request
http.staleConnectionCheckEnabled: true
# Available idle connection expiration time , When reusing an idle connection, it will first check whether the idle time exceeds this time, and if it exceeds, release it socket Re-establish
http.validateAfterInactivity: 3000000
3. Initialize the connection pool
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); // Maximum number of connections
connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); // Maximum number of connections per route
connectionManager.setValidateAfterInactivity(validateAfterInactivity); // Maximum spatial time
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(socketTimeout) // Server returns data (response) Exceeds the time of throwing read timeout
.setConnectTimeout(connectTimeout) // Connect to the server ( Successful handshake ) Time beyond throwing connect timeout
.setStaleConnectionCheckEnabled(staleConnectionCheckEnabled) // Check whether it is available before submission
.setConnectionRequestTimeout(connectionRequestTimeout)// Gets the connection timeout from the connection pool. If the timeout does not get an available connection, it will throw org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
.build();
return HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(connectionManager)
.build();
}
}
4. Using examples
RestTemplate is an encapsulation of HttpCilent, so HttpCilent can continue to be used according to HttpCilent. Look at the difference between the two
HttpCilent:
@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:
@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 is more concise.
3. Common methods of RestTemplate
1. getForEntity
The return value of the getForEntity method is 1 ResponseEntity < T > , ResponseEntity < T > Spring is the encapsulation of HTTP request response, including several important elements, such as response code, contentType, contentLength, response message body and so on. For example, the following example:
@RequestMapping("/sayhello")
public String sayHello() {
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={1}", String.class, " Zhang 3");
return responseEntity.getBody();
}
@RequestMapping("/sayhello2")
public String sayHello2() {
Map<String, String> map = new HashMap<>();
map.put("name", " Li 4");
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={name}", String.class, map);
return responseEntity.getBody();
}
2. getForObject
The getForObject function is actually a step forward encapsulation of the getForEntity function. If you only pay attention to the content of the returned message body and don't pay attention to other information, at this time,
You can use getForObject to give a simple example, as follows:
@RequestMapping("/book2")
public Book book2() {
Book book = restTemplate.getForObject("http://HELLO-SERVICE/getbook1", Book.class);
return book;
}
3. postForEntity
@RequestMapping("/book3")
public Book book3() {
Book book = new Book();
book.setName(" Dream of Red Mansions ");
ResponseEntity<Book> responseEntity = restTemplate.postForEntity("http://HELLO-SERVICE/getbook2", book, Book.class);
return responseEntity.getBody();
}
The first parameter of the method represents the address of the service to be invoked
The second parameter of the method represents the uploaded parameter
The third parameter of the method represents the data type of the returned message body
4. postForObject
If you only pay attention to the returned message body, you can use postForObject directly. Usage and getForObject1.
5. postForLocation
postForLocation is also a new resource submitted. After successful submission, the parameters of URI and postForLocation returning the new resource are basically the same as those of the previous two, except that the return value of this method is Uri, which only requires the service provider to return one Uri, and the Uri indicates the location of the new resource.
6. PUT Request
In RestTemplate, the PUT request can be invoked through the put method, and the parameters of the put method are basically the same as those of the postForEntity method described earlier, except that the put method has no return value. Give a simple example, as follows:
@RequestMapping("/put")
public void put() {
Book book = new Book();
book.setName(" Dream of Red Mansions ");
restTemplate.put("http://HELLO-SERVICE/getbook3/{1}", book, 99);
}
7. DELETE Request
<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>
0