RestTemplate使用教程

一、概述

  spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。

  在Spring应用程序中访问第三方REST服务与使用Spring RestTemplate类有关。RestTemplate类的设计原则与许多其他Spring *模板类(例如JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。

  RestTemplate默认依赖JDK提供http连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。

  考虑到RestTemplate类是为调用REST服务而设计的,因此它的主要方法与REST的基础紧密相连就不足为奇了,后者是HTTP协议的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS。例如,RestTemplate类具有headForHeaders()、getForObject()、postForObject()、put()和delete()等方法

二、实现

最新api地址:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

RestTemplate包含以下几个部分:

  • HttpMessageConverter 对象转换器
  • ClientHttpRequestFactory 默认是JDK的HttpURLConnection
  • ResponseErrorHandler 异常处理
  • ClientHttpRequestInterceptor 请求拦截器

常规配置

 public MyRestClientService(RestTemplateBuilder restTemplateBuilder) {  
        this.restTemplate = restTemplateBuilder  
            .basicAuthorization("username", "password")  
            .setConnectTimeout(3000)  
            .setReadTimeout(5000)  
            .rootUri("http://api.example.com/")  
            .build();  
    }

ClientHttpRequestInterceptor

学习使用带有Spring RestTemplate的ClientHttpRequestInterceptor,以Spring AOP风格记录请求和响应头和主体。

拦截器记录请求和响应
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StreamUtils;
  
import java.io.IOException;
import java.nio.charset.Charset;
 
public class RequestResponseLoggingInterceptor implements ClientHttpRequestInterceptor {
      
    private final Logger log = LoggerFactory.getLogger(this.getClass());
  
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException
    {
        logRequest(request, body);
        ClientHttpResponse response = execution.execute(request, body);
        logResponse(response);
 
        //Add optional additional headers
        response.getHeaders().add("headerName", "VALUE");
 
        return response;
    }
  
    private void logRequest(HttpRequest request, byte[] body) throws IOException
    {
        if (log.isDebugEnabled())
        {
            log.debug("===========================request begin================================================");
            log.debug("URI         : {}", request.getURI());
            log.debug("Method      : {}", request.getMethod());
            log.debug("Headers     : {}", request.getHeaders());
            log.debug("Request body: {}", new String(body, "UTF-8"));
            log.debug("==========================request end================================================");
        }
    }
  
    private void logResponse(ClientHttpResponse response) throws IOException
    {
        if (log.isDebugEnabled())
        {
            log.debug("============================response begin==========================================");
            log.debug("Status code  : {}", response.getStatusCode());
            log.debug("Status text  : {}", response.getStatusText());
            log.debug("Headers      : {}", response.getHeaders());
            log.debug("Response body: {}", StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()));
            log.debug("=======================response end=================================================");
        }
    }
}
注册ClientHttpRequestInterceptor
@Bean
public RestTemplate restTemplate(){
    RestTemplate restTemplate = new RestTemplate();
 
    restTemplate.setRequestFactory(newBufferingClientHttpRequestFactory(clientHttpRequestFactory()));
    restTemplate.setMessageConverters(Collections.singletonList(mappingJacksonHttpMessageConverter()));
 
    restTemplate.setInterceptors( Collections.singletonList(newRequestResponseLoggingInterceptor()) );
 
    return restTemplate;
}

三、请求示例

GET

private static void getEmployees(){
    final String uri = "http://localhost:8080/springrestexample/employees";
     
    RestTemplate restTemplate = new RestTemplate();
    String result = restTemplate.getForObject(uri, String.class);
     
    System.out.println(result);
}
使用RestTemplate定制HTTP头文件
private static void getEmployees(){
    final String uri = "http://localhost:8080/springrestexample/employees";
     
    RestTemplate restTemplate = new RestTemplate();
     
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
     
    ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
     
    System.out.println(result);
}
Get请求获取响应为一个对象
private static void getEmployees(){
    final String uri = "http://localhost:8080/springrestexample/employees";
    RestTemplate restTemplate = new RestTemplate();
     
    EmployeeListVO result = restTemplate.getForObject(uri, EmployeeListVO.class);
     
    System.out.println(result);
}
URL 参数
private static void getEmployeeById(){
    final String uri = "http://localhost:8080/springrestexample/employees/{id}";
     
    Map<String, String> params = new HashMap<String, String>();
    params.put("id", "1");
     
    RestTemplate restTemplate = new RestTemplate();
    EmployeeVO result = restTemplate.getForObject(uri, EmployeeVO.class, params);
     
    System.out.println(result);
}

POST

private static void createEmployee(){
    final String uri = "http://localhost:8080/springrestexample/employees";
 
    EmployeeVO newEmployee = new EmployeeVO(-1, "Adam", "Gilly", "test@email.com");
 
    RestTemplate restTemplate = new RestTemplate();
    EmployeeVO result = restTemplate.postForObject( uri, newEmployee, EmployeeVO.class);
 
    System.out.println(result);
}
Submit Form Data
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
 
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.add("id", "1");
 
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
 
RestTemplate restTemplate = new RestTemplate();
EmployeeVO result = restTemplate.postForObject( uri, request, EmployeeVO.class);
System.out.println(result);

PUT

private static void updateEmployee(){
    final String uri = "http://localhost:8080/springrestexample/employees/{id}";
     
    Map<String, String> params = new HashMap<String, String>();
    params.put("id", "2");
     
    EmployeeVO updatedEmployee = new EmployeeVO(2, "New Name", "Gilly", "test@email.com");
     
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.put ( uri, updatedEmployee, params);
}
Simple PUT 
Foo updatedInstance = new Foo("newName");
updatedInstance.setId(createResponse.getBody().getId());
String resourceUrl = 
  fooResourceUrl + '/' + createResponse.getBody().getId();
HttpEntity<Foo> requestUpdate = new HttpEntity<>(updatedInstance, headers);
template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class);
使用.exchange和请求回调
RequestCallback requestCallback(final Foo updatedInstance) {
    return clientHttpRequest -> {
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(clientHttpRequest.getBody(), updatedInstance);
        clientHttpRequest.getHeaders().add(
          HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        clientHttpRequest.getHeaders().add(
          HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass());
    };
}

DELETE

private static void deleteEmployee(){
    final String uri = "http://localhost:8080/springrestexample/employees/{id}";
     
    Map<String, String> params = new HashMap<String, String>();
    params.put("id", "2");
     
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.delete ( uri,  params );
}

参考资料:

https://howtodoinjava.com/spring-restful/spring-restful-client-resttemplate-example/

https://www.xncoding.com/2017/07/06/spring/sb-restclient.html

https://www.baeldung.com/rest-template

posted @ 2020-01-03 13:45  不死码农  阅读(15945)  评论(1编辑  收藏  举报