RestTemplate is often used as a substitute for OKHttp, HttpClient and other utility classes by unsuspecting developers, but the two are fundamentally different. The OKHttp and HttpClient utility classes are used by Java to send Http requests. This is often used in daily development, but RestTemplate is not intended to replace the use of Http utility classes. Instead, it can use various Http utility classes underneath. It is intended more to simplify the use of Http utility classes, and you can enhance RestTemplate functionality through Spring annotations, such as configuring load balancing.
Configuration RestTemplate
@Configuration
@Slf4j
public class RestTemplateConfig {
@Bean
@LoadBalanced //RestTemplate Load balancing takes effect
public RestTemplate getRestTemplate(a){
OkHttpClient okHttpClient = OkHttpClientObject.CLIENT.getClientInstance();
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new OkHttp3ClientHttpRequestFactory(okHttpClient)); // Configure the utility class used by OKHttp
returnrestTemplate; }}Copy the code
RestTemplate call
There are many methods to call RestTemplate. RestTemplate provides common get, POST, and PUT methods. This section uses the POST method as an example.
// Header level submitted Post arguments are wrapped as HttpEntity, if you do not want to parse the returned argument, (it can return a String unified private String sendRequestByRestTemplate wrapper, String serviceName, String path) { try { String reqUrl = String.format("http://%s%s",serviceName,path); HttpHeaders headers = getHttpHeaders(wrapper, reqUrl); HttpEntity<String> reqData = new HttpEntity<> (IOUtils.toString(wrapper.getReader()),headers); String result = restTemplate.postForObject(reqUrl,reqData,String.class); return result; }catch (Exception e){ log.info("rpc send request failed [{}]",e.getMessage()); return ""; }}Copy the code
The header method looks like this:
private HttpHeaders getHttpHeaders(HttpServletRequest wrapper, String reqUrl) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); Enumeration<String> originHeadersNames = wrapper.getHeaderNames(); while (originHeadersNames.hasMoreElements()){ String name = originHeadersNames.nextElement(); if(! name.contains("x-hmac-auth")){ headers.add(name, wrapper.getHeader(name)); } } return headers; }Copy the code
Note that if you want to enable load balancing, the URL in the RestTemplate must be in the format http://${serviceId}/${requestPath}, where serviceId is the name of the service registered in Eureka, RequestPath is the requestPath. For specific reasons, please refer to the following code:
public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {// use servieId to find the loadBalancer ILoadBalancer loadBalancer = this.getloadbalancer (serviceId); Server server = this.getServer(loadBalancer, hint); if (server == null) { throw new IllegalStateException("No instances available for " + serviceId); } else { RibbonLoadBalancerClient.RibbonServer ribbonServer = new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server)); return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request); }}Copy the code
Most developers know that RestTemplate supports a load balancer, but if you use it without paying attention to the request format of the call, it is possible to throw an exception without finding a valid back-end call service address.
summary
These are some of the small things I learned from using RestTemplate. I hope I can help you. The next article looks at the source code for RestTemplate.