文档章节

Spring Boot 入门 - 进阶篇(4)- REST访问(RestTemplate)

o
 onedotdot
发布于 10/17 09:24
字数 792
阅读 34
收藏 4

经常需要发送一个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+

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

本文转载自:http://rensanning.iteye.com/blog/2362105

共有 人打赏支持
o
粉丝 8
博文 352
码字总数 14350
作品 0
朝阳
私信 提问
疯狂Spring Cloud连载(9)——RestTemplate的负载均衡原理

本文节选自《疯狂Spring Cloud微服务架构实战》 京东购买地址:https://item.jd.com/12256011.html 当当网购买地址:http://product.dangdang.com/25201393.html Spring Cloud教学视频:htt...

杨大仙的程序空间
2017/10/18
0
2
Spring Cloud Netfix Hystrix断路器例子

1.概述 在本文中我们将介绍Spring Cloud Netflix Hystrix - 断路器。我们将使用该库来实现断路器的企业模式,该模式描述了应用程序中不同级别的故障级联策略。 断路器的工作原理类似于电子产...

RaiseHead
08/16
0
0
Spring Cloud 安全:集成OAuth2实现身份认证和单点登录

1、概述 Spring Cloud 的安全模块可以为Spring Boot应用提供基于令牌的安全特性。具体讲就是支持OAuth2协议来实现单点登录(SSO),可以很方便地在资源服务之间传递身份令牌,以及使用嵌入式...

RaiseHead
07/20
0
0
白话SpringCloud | 第四章:服务消费者(Ribbon+Feign)

前言 上两章节,介绍了下关于注册中心-Eureka的使用及高可用的配置示例,本章节开始,来介绍下服务和服务之间如何进行服务调用的,同时会讲解下几种不同方式的服务调用。 一点知识 在体系中,...

oKong
09/21
0
0
UDF 集成样例--udf-sample

UDF 基于spring boot / spring cloud 的基础项目,脚手架,主要用于学习和实践 按照spring boot的思想,将各个不同的功能按照starter的形式拆分开来,做到灵活组合 物理架构示意 CI & CD 示意 代...

wangkang80
2017/08/27
344
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS 安装PHP5和PHP7

安装PHP5 下载解压二进制包 [root@test-a src]# cd /usr/local/src/[root@test-a src]# wget http://cn2.php.net/distributions/php-5.6.32.tar.bz2[root@test-a src]# tar jxvf php-5.6......

野雪球
今天
4
0
windows上类似dnsmasq的软件Dual DHCP DNS Server

官网地址:http://dhcp-dns-server.sourceforge.net/官网定向的下载地址:https://sourceforge.net/projects/dhcp-dns-server/files/ 设置参考地址:http://blog.51cto.com/zhukeqiang/18264......

xueyuse0012
今天
3
0
LinkedHashMap源码解析

前言 HashMap中的元素时无序的,也就是说遍历HashMap的时候,顺序和放入的顺序是不一样的。 如果需要有序的Map,就可以采用LinkedHashMap. LinkedHashMap通过维护一个包含所有元素的双向链表,...

grace_233
今天
3
0
初识flask

文档 0.10.1版本 http://www.pythondoc.com/flask/index.html 1.0.2版本 https://dormousehole.readthedocs.io/en/latest/ 安装flask $ pip3 install flaskCollecting flask Downloading......

yimingkeji
昨天
5
0
Akka系统《sixteen》译

Actor是一个封装状态(state)和行为(behavior)的对象,它们只通过交换消息通信(放入收件人邮箱的邮件)。从某种意义上说,Actor是最严格的面向对象编程形式,但它更适合将他们视为人:在与Act...

woshixin
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部