zoukankan      html  css  js  c++  java
  • REST访问(RestTemplate)



    https://www.cnblogs.com/softidea/p/6910198.html

    经常需要发送一个GET/POST请求到其他系统(REST API),通过JDK自带的HttpURLConnection、Apache HttpClient、Netty 4、OkHTTP 2/3都可以实现。

    HttpClient的使用:http://rensanning.iteye.com/blog/1550436

    Spring的RestTemplate封装了这些库的实现,使用起来更简洁。

    RestTemplate包含以下几个部分: 
    HttpMessageConverter 对象转换器
    ClientHttpRequestFactory 默认是JDK的HttpURLConnection
    ResponseErrorHandler 异常处理
    ClientHttpRequestInterceptor 请求拦截器

    @Service  
    public class AccountService {  
      
        @Autowired  
        private RestTemplate restTemplate;  
      
        // ...  
      
    }  

    (1)发送GET请求(getForObject()、getForEntity()、exchange()) 

    // 1-getForObject()  
    User user1 = this.restTemplate.getForObject(uri, User.class);  
      
    // 2-getForEntity()  
    ResponseEntity<User> responseEntity1 = this.restTemplate.getForEntity(uri, User.class);  
    HttpStatus statusCode = responseEntity1.getStatusCode();  
    HttpHeaders header = responseEntity1.getHeaders();  
    User user2 = responseEntity1.getBody();  
      
    // 3-exchange()  
    RequestEntity requestEntity = RequestEntity.get(new URI(uri)).build();  
    ResponseEntity<User> responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);  
    User user3 = responseEntity2.getBody();  
     

    (2)发送POST请求(postForObject()、postForEntity()、exchange()) 

    // 1-postForObject()  
    User user1 = this.restTemplate.postForObject(uri, user, User.class);  
      
    // 2-postForEntity()  
    ResponseEntity<User> responseEntity1 = this.restTemplate.postForEntity(uri, user, User.class);  
      
    // 3-exchange()  
    RequestEntity<User> requestEntity = RequestEntity.post(new URI(uri)).body(user);  
    ResponseEntity<User> responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);  


    (3)设置HTTP Header信息 

    // 1-Content-Type  
    RequestEntity<User> requestEntity = RequestEntity  
            .post(new URI(uri))  
            .contentType(MediaType.APPLICATION_JSON)  
            .body(user);  
      
    // 2-Accept  
    RequestEntity<User> requestEntity = RequestEntity  
            .post(new URI(uri))  
            .accept(MediaType.APPLICATION_JSON)  
            .body(user);  
      
    // 3-Other  
    RequestEntity<User> requestEntity = RequestEntity  
            .post(new URI(uri))  
            .header("Authorization", "Basic " + base64Credentials)  
            .body(user);  

    (4)异常处理 

    捕获HttpServerErrorException 

    int retryCount = 0;  
    while (true) {  
        try {  
            responseEntity = restTemplate.exchange(requestEntity, String.class);  
            break;  
        } catch (HttpServerErrorException e) {  
            if (retryCount == 3) {  
                throw e;  
            }  
            retryCount++;  
        }  
    }  
     

    自定义异常处理 

    public class CustomErrorHandler extends DefaultResponseErrorHandler {  
      
        @Override  
        public void handleError(ClientHttpResponse response) throws IOException {  
      
        }  
      
    }  
    @Configuration  
    public class RestClientConfig {  
      
        @Bean  
        public RestTemplate restTemplate() {  
            RestTemplate restTemplate = new RestTemplate();  
            restTemplate.setErrorHandler(new CustomErrorHandler());  
            return restTemplate;  
        }  
      
    }  
     


    (5)设置超时时间 

    @Configuration  
    public class RestClientConfig {  
      
        @Bean  
        public RestTemplate restTemplate() {  
            return new RestTemplate(clientHttpRequestFactory());  
        }  
      
        private ClientHttpRequestFactory clientHttpRequestFactory() {  
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();  
            factory.setReadTimeout(2000);  
            factory.setConnectTimeout(2000);  
            return factory;  
        }  
    }  
     


    (6)设置连接池 

    @Configuration  
    public class RestClientConfig {  
      
      @Bean  
      public ClientHttpRequestFactory httpRequestFactory() {  
        return new HttpComponentsClientHttpRequestFactory(httpClient());  
      }  
      
      @Bean  
      public RestTemplate restTemplate() {  
        return new RestTemplate(httpRequestFactory());  
      }  
      
      @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(5);  
        connectionManager.setDefaultMaxPerRoute(5);  
      
        RequestConfig requestConfig = RequestConfig.custom()  
            .setSocketTimeout(8000)  
            .setConnectTimeout(8000)  
            .setConnectionRequestTimeout(8000)  
            .build();  
      
        return HttpClientBuilder.create()  
            .setDefaultRequestConfig(requestConfig)  
            .setConnectionManager(connectionManager)  
            .build();  
      }  
      
    }  
     

    (7)发送文件 

    MultiValueMap<String, Object> multiPartBody = new LinkedMultiValueMap<>();  
    multiPartBody.add("file", new ClassPathResource("/tmp/user.txt"));  
    RequestEntity<MultiValueMap<String, Object>> requestEntity = RequestEntity  
            .post(uri)  
            .contentType(MediaType.MULTIPART_FORM_DATA)  
            .body(multiPartBody);  
     

    (8)下载文件 

    // 小文件  
    RequestEntity requestEntity = RequestEntity.get(uri).build();  
    ResponseEntity<byte[]> responseEntity = restTemplate.exchange(requestEntity, byte[].class);  
    byte[] downloadContent = responseEntity.getBody();  
      
    // 大文件  
    ResponseExtractor<ResponseEntity<File>> responseExtractor = new ResponseExtractor<ResponseEntity<File>>() {  
        @Override  
        public ResponseEntity<File> extractData(ClientHttpResponse response) throws IOException {  
            File rcvFile = File.createTempFile("rcvFile", "zip");  
            FileCopyUtils.copy(response.getBody(), new FileOutputStream(rcvFile));  
            return ResponseEntity.status(response.getStatusCode()).headers(response.getHeaders()).body(rcvFile);  
        }  
    };  
    File getFile = this.restTemplate.execute(targetUri, HttpMethod.GET, null, responseExtractor);  
     

    (9)Spring Boot的RestTemplateBuilder 

    全局设置 

    @Component  
    public class CustomRestTemplateCustomizer implements RestTemplateCustomizer {  
        @Override  
        public void customize(RestTemplate restTemplate) {  
            new RestTemplateBuilder()  
                    .detectRequestFactory(false)  
                    .basicAuthorization("username", "password")  
                    .uriTemplateHandler(new OkHttp3ClientHttpRequestFactory())  
                    .errorHandler(new CustomResponseErrorHandler())  
                    .configure(restTemplate);  
        }  
    }  
     


    单独设置 

    @Service  
    public class MyRestClientService {  
      
        private RestTemplate restTemplate;  
      
        public MyRestClientService(RestTemplateBuilder restTemplateBuilder) {  
            this.restTemplate = restTemplateBuilder  
                .basicAuthorization("username", "password")  
                .setConnectTimeout(3000)  
                .setReadTimeout(5000)  
                .rootUri("http://api.example.com/")  
                .errorHandler(new CustomResponseErrorHandler())  
                .additionalMessageConverters(new CustomHttpMessageConverter())  
                .uriTemplateHandler(new OkHttp3ClientHttpRequestFactory())  
                .build();  
        }  
      
        public String site() {  
            return this.restTemplate.getForObject("http://rensanning.iteye.com/", String.class);  
        }  
      
    }  

    http://rensanning.iteye.com/blog/2362105

  • 相关阅读:
    第九篇装饰器基本原理
    第八篇迭代器协议和生产器
    python第六篇文件处理类型
    Python开发【第十篇】:模块
    习题练习
    2.2.6 集合
    第七篇 python基础之函数,递归,内置函数
    Python开发【第五篇】:Python基础之杂货铺
    Python开发【第四篇】:Python基础之函数
    详解CSS position属性
  • 原文地址:https://www.cnblogs.com/softidea/p/9438783.html
Copyright © 2011-2022 走看看