Spring specific methods used by RestTemplata

  • 2021-01-14 05:50:34
  • OfStack

The basic concept

Spring RestTemplate is a client provided by Spring for accessing Rest services. RestTemplate provides a variety of convenient ways to access remote Http services, which can greatly improve the efficiency of the client writing, so many clients such as Android or third party service providers are using RestTemplate to request restful services.

spring- RestTemplata of web is the encapsulation of java's underlying http. Using RestTemplata users can no longer care about the underlying connection establishment, and RestTemplata not only supports the Rest specification, but also can define the return value object type.

In use, we can directly new1 RestTemplate object, in the RestTemplate object we create there will be some message converter, according to the returned data MediaType to find the corresponding converter and MediaType conversion. You can also create a message converter yourself, creating a class that inherits AbstractGenericHttpMessageConverter < T > Class or implement HttpMessageConverter < T > In the writeInternal or write methods, parameters are written to the stream, and in the readInternal or read methods, the return result is fetched from the stream's body and typed.

RestTemplate objects create HTTP requests at the bottom level using the implementation under the java.net package. Different HTTP requests can be specified using ClientHttpRequestFactory.

The ClientHttpRequestFactory interface provides two main implementations:

The first is SimpleClientHttpRequestFactory, which creates the underlying Http request connection using the method provided by J2SE (that is, the method provided by the java.net package). The first way is to use HttpComponentsClientHttpRequestFactory. The bottom level uses HttpClient to access remote Http services. With HttpClient, information such as connection pool and certificate can be configured.

RestTemplate uses SimpleClientHttpRequestFactory by default, and HttpConnection calls jdk internally. The default timeout is -1. We can define the timeout by ourselves


SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
// Sets the connection timeout in milliseconds 
factory.setConnectTimeout(5000);
// Sets the read timeout in milliseconds 
factory.setReadTimeout(10000);
RestTemplate restTemplate = new RestTemplate(factory);

Request using GET:


String url = "http://localhost:80/mandy/login.json?account=123456&password=123456";
Result res = restTemplate.getForObject(url, Result.class);

RestTemplate source code:


  @Override
 public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws RestClientException {
  RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
  HttpMessageConverterExtractor<T> responseExtractor =
    new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
  return execute(url, HttpMethod.GET, requestCallback, responseExtractor, urlVariables);
 }

It is best to use get request to concatenate the parameters directly to the address. For some reason, if you use the third parameter, even MultiValueMap type will not work.

Request using POST:


HashMap<String, Object> map = new HashMap<String, Object>();
 map.put("name", " test ");
 map.put("account", "qwer");
 map.put("password", "qwer");
 ObjectMapper mapper = new ObjectMapper();
 String jsonStr = null;
 try {
   jsonStr = mapper.writeValueAsString(map);
 } catch (Exception e) {
   e.printStackTrace();
 }
// create HTTP Header entities that fill in header information, such as data formats 
 HttpHeaders httpHeaders = new HttpHeaders();
 httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
// create HTTP Entity into which the request body and request header can be placed directly using the constructor 
 HttpEntity<String> httpEntity = new HttpEntity<String>(jsonStr2, httpHeaders);
String url = "http://localhost:80/mandy/user_enable.json";
// Call the method to make the request 
 Result res2 = restTemplate.postForObject(url, httpEntity, Result.class);

RestTemplate source code:


  @Override
 public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
   throws RestClientException {

  RequestCallback requestCallback = httpEntityCallback(request, responseType);
  HttpMessageConverterExtractor<T> responseExtractor =
    new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
  return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
 }

Request using PUT:


HashMap<String, Object> map = new HashMap<String, Object>();
map.put("user_id", "1");
map.put("enable", 0);
ObjectMapper mapper = new ObjectMapper();
String jsonStr = null;
try {
 jsonStr = mapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
 e.printStackTrace();
}
// create HTTP Header entities that fill in header information, such as data formats 
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
// create HTTP Entity into which the request body and request header can be placed directly using the constructor 
HttpEntity<String> httpEntity = new HttpEntity<String>(jsonStr, httpHeaders);  
String url = "http://localhost:80/mandy/user_enable.json";
restTemplate.put(url , httpEntity);

RestTemplate source code:


  @Override
 public void put(String url, Object request, Object... urlVariables) throws RestClientException {
  RequestCallback requestCallback = httpEntityCallback(request);
  execute(url, HttpMethod.PUT, requestCallback, null, urlVariables);
 }

A minor drawback to this method is that there is no return value for the result of the request. If you need a return value, you cannot use this method.

If you want to use delete type requests, RestTemplate's put method has only the following types of parameter columns


@Override
public void delete(String url, Object... urlVariables) throws RestClientException {
  execute(url, HttpMethod.DELETE, null, null, urlVariables);
}

@Override
public void delete(String url, Map<String, ?> urlVariables) throws RestClientException {
  execute(url, HttpMethod.DELETE, null, null, urlVariables);
}

@Override
public void delete(URI url) throws RestClientException {
  execute(url, HttpMethod.DELETE, null, null);
}

These methods do not give us arguments to put the body of the request, so to use the Delete method provided by RestTemplate directly, the interface must use the restful style, put the arguments in the address, and get the arguments via the @PathVariable(value="") annotation.

Important: In fact, we can directly use exchange method of RestTemplate, as follows


@Override
public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
  HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException {

  RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
  ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
  return execute(url, method, requestCallback, responseExtractor, uriVariables);
}

Only 1 method is listed here, others can see the source code, this method can do all types of requests.

In this method, method parameters can be obtained by HTTPMethod enumeration, requestEntity parameters are encapsulated HttpEntity entity, contains the request body and head, responseType parameters is to return the result of mapping class, uriVariables this parameter impressed me is the chicken ribs (personal opinion), get request return interface can be through the method return value getBody () method.


Related articles: