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

来源:博客园

—— 完 ——
相关推荐
评论

立 为 非 似

中 谁 昨 此

宵 风 夜 星

。 露 , 辰

文章点击榜

细 无 轻 自

如 边 似 在

愁 丝 梦 飞

。 雨 , 花