博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Boot 入门 - 进阶篇(4)- REST访问(RestTemplate)
阅读量:7034 次
发布时间:2019-06-28

本文共 6324 字,大约阅读时间需要 21 分钟。

hot3.png

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

HttpClient的使用: 
Spring的RestTemplate封装了这些库的实现,使用起来更简洁。 
RestTemplate包含以下几个部分: 

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

cce612d5-bc90-3b56-a877-264cdc10df6b.png

Java代码 

 收藏代码

  1.   
  2. public class AccountService {  
  3.   
  4.     @Autowired  
  5.     private RestTemplate restTemplate;  
  6.   
  7.     // ...  
  8.   
  9. }  

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

 收藏代码

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

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

 收藏代码

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

(3)设置HTTP Header信息 
Java代码 

 收藏代码

  1. // 1-Content-Type  
  2. RequestEntity<User> requestEntity = RequestEntity  
  3.         .post(new URI(uri))  
  4.         .contentType(MediaType.APPLICATION_JSON)  
  5.         .body(user);  
  6.   
  7. // 2-Accept  
  8. RequestEntity<User> requestEntity = RequestEntity  
  9.         .post(new URI(uri))  
  10.         .accept(MediaType.APPLICATION_JSON)  
  11.         .body(user);  
  12.   
  13. // 3-Other  
  14. RequestEntity<User> requestEntity = RequestEntity  
  15.         .post(new URI(uri))  
  16.         .header("Authorization", "Basic " + base64Credentials)  
  17.         .body(user);  

(4)异常处理 
捕获HttpServerErrorException 
Java代码 

 收藏代码

  1. int retryCount = 0;  
  2. while (true) {  
  3.     try {  
  4.         responseEntity = restTemplate.exchange(requestEntity, String.class);  
  5.         break;  
  6.     } catch (HttpServerErrorException e) {  
  7.         if (retryCount == 3) {  
  8.             throw e;  
  9.         }  
  10.         retryCount++;  
  11.     }  
  12. }  

自定义异常处理 
Java代码 

 收藏代码

  1. public class CustomErrorHandler extends DefaultResponseErrorHandler {  
  2.   
  3.       
  4.     public void handleError(ClientHttpResponse response) throws IOException {  
  5.   
  6.     }  
  7.   
  8. }  

Java代码 

 收藏代码

  1. @Configuration  
  2. public class RestClientConfig {  
  3.   
  4.       
  5.     public RestTemplate restTemplate() {  
  6.         RestTemplate restTemplate = new RestTemplate();  
  7.         restTemplate.setErrorHandler(new CustomErrorHandler());  
  8.         return restTemplate;  
  9.     }  
  10.   
  11. }  

(5)设置超时时间 
Java代码 

 收藏代码

  1. @Configuration  
  2. public class RestClientConfig {  
  3.   
  4.     @Bean  
  5.     public RestTemplate restTemplate() {  
  6.         return new RestTemplate(clientHttpRequestFactory());  
  7.     }  
  8.   
  9.     private ClientHttpRequestFactory clientHttpRequestFactory() {  
  10.         HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();  
  11.         factory.setReadTimeout(2000);  
  12.         factory.setConnectTimeout(2000);  
  13.         return factory;  
  14.     }  
  15. }  

(6)设置连接池 
Java代码 

 收藏代码

  1. @Configuration  
  2. public class RestClientConfig {  
  3.   
  4.   @Bean  
  5.   public ClientHttpRequestFactory httpRequestFactory() {  
  6.     return new HttpComponentsClientHttpRequestFactory(httpClient());  
  7.   }  
  8.   
  9.   @Bean  
  10.   public RestTemplate restTemplate() {  
  11.     return new RestTemplate(httpRequestFactory());  
  12.   }  
  13.   
  14.   @Bean  
  15.   public HttpClient httpClient() {  
  16.     Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create()  
  17.         .register("http", PlainConnectionSocketFactory.getSocketFactory())  
  18.         .register("https", SSLConnectionSocketFactory.getSocketFactory())  
  19.         .build();  
  20.     PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);  
  21.     connectionManager.setMaxTotal(5);  
  22.     connectionManager.setDefaultMaxPerRoute(5);  
  23.   
  24.     RequestConfig requestConfig = RequestConfig.custom()  
  25.         .setSocketTimeout(8000)  
  26.         .setConnectTimeout(8000)  
  27.         .setConnectionRequestTimeout(8000)  
  28.         .build();  
  29.   
  30.     return HttpClientBuilder.create()  
  31.         .setDefaultRequestConfig(requestConfig)  
  32.         .setConnectionManager(connectionManager)  
  33.         .build();  
  34.   }  
  35.   
  36. }  

(7)发送文件 
Java代码 

 收藏代码

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

(8)下载文件 
Java代码 

 收藏代码

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

(9)Spring Boot的RestTemplateBuilder 
全局设置 
Java代码 

 收藏代码

  1. @Component  
  2. public class CustomRestTemplateCustomizer implements RestTemplateCustomizer {  
  3.     @Override  
  4.     public void customize(RestTemplate restTemplate) {  
  5.         new RestTemplateBuilder()  
  6.                 .detectRequestFactory(false)  
  7.                 .basicAuthorization("username", "password")  
  8.                 .uriTemplateHandler(new OkHttp3ClientHttpRequestFactory())  
  9.                 .errorHandler(new CustomResponseErrorHandler())  
  10.                 .configure(restTemplate);  
  11.     }  
  12. }  

单独设置 
Java代码 

 收藏代码

  1. @Service  
  2. public class MyRestClientService {  
  3.   
  4.     private RestTemplate restTemplate;  
  5.   
  6.     public MyRestClientService(RestTemplateBuilder restTemplateBuilder) {  
  7.         this.restTemplate = restTemplateBuilder  
  8.             .basicAuthorization("username", "password")  
  9.             .setConnectTimeout(3000)  
  10.             .setReadTimeout(5000)  
  11.             .rootUri("http://api.example.com/")  
  12.             .errorHandler(new CustomResponseErrorHandler())  
  13.             .additionalMessageConverters(new CustomHttpMessageConverter())  
  14.             .uriTemplateHandler(new OkHttp3ClientHttpRequestFactory())  
  15.             .build();  
  16.     }  
  17.   
  18.     public String site() {  
  19.         return this.restTemplate.getForObject("http://rensanning.iteye.com/", String.class);  
  20.     }  
  21.   
  22. }  

参考: 
http://qiita.com/kazuki43zoo/items/7cf3c8ca4f6f2283cefb 
http://terasolunaorg.github.io/guideline/5.1.0.RELEASE/ja/ArchitectureInDetail/RestClient.html

转载于:https://my.oschina.net/newchaos/blog/2247743

你可能感兴趣的文章
管理Java垃圾回收的五个建议
查看>>
如何对 Android 库进行依赖管理?
查看>>
前端新人初体验啊丶
查看>>
小菜鸟的2015年总结
查看>>
[Leetcode] Gas Station 加油站
查看>>
Objective-C实例变量
查看>>
容器技术毫无悬念主宰本次Amazon Re:Invent
查看>>
内存泄露从入门到精通三部曲之常见原因与用户实践
查看>>
js基础笔记-类型装换
查看>>
win7-x64上MySql的初次安装
查看>>
自定义初学1——扩展系统控件
查看>>
docker进阶与实战 1 docker简介
查看>>
日常环境莫名宕机的处理
查看>>
获5.3亿美金融资,亚马逊、红杉入局,自动驾驶“梦之队”Aurora还藏了哪些秘招? ...
查看>>
PreparedStatement 基于mysql数据库做分页查询和统计查询 ...
查看>>
机器人军团和傅盛的答案
查看>>
阿里云年营收突破200亿 成亚洲最大云服务商
查看>>
移动数据安全怎么防护?
查看>>
新功能: 阿里云爬虫风险管理利器 - 实时日志分析 (一)
查看>>
如何优化Spring Cloud微服务注册中心架构?
查看>>