Spring Boot 入门

白昼怎懂夜的黑 提交于 2019-11-30 00:53:44

经常需要发送一个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 请求拦截器



Java代码 

 

  1. @Service  
  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.     @Override  
  4.     public void handleError(ClientHttpResponse response) throws IOException {  
  5.   
  6.     }  
  7.   
  8. }  


Java代码 

 

  1. @Configuration  
  2. public class RestClientConfig {  
  3.   
  4.     @Bean  
  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

程序猿必关注这个技术,风头正劲,仅4个月薪酬35K+

大数据技术与运用的成熟,应用集中于互联网、金融、医疗、新能源、通信和房地产等行业。整理平均薪资情况和大数据学习大纲供查看

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!