一. 前言 :

小熙前段时间忙于微服务系统的开发,在远程调用的时候,有用到restTempalte的使用,就自己封装了一个抽取工具类。后来,由于系统慢慢的整合一些东西,restTempalte埋的坑太多,所以后续有去用到feign了,此案例还是建议相对自己的项目去抉择吧。

二. 视图:

展示图:

三. 依赖 :

有一些特殊的依赖,标注下(也可以不导入,可以手动实现相关,不过比较麻烦)

  1. 糊涂工具坐标

          <!-- 糊涂工具类 --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.0.7</version></dependency>
    
  2. 谷歌工具坐标

           <!--谷歌工具类--><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version></dependency>
    
  3. 分页工具类(可以替换成自己项目环境的,小熙替换了自己项目的写了一个简易的示例)

    package com.chengxi.datalom.utils.rest;import io.swagger.annotations.ApiModelProperty;
    import lombok.AllArgsConstructor;
    import lombok.Data;import java.util.ArrayList;
    import java.util.List;/*** @author chengxi* @date 2020/7/13 17:21*/
    @Data
    @AllArgsConstructor
    public class PageVO<T> {@ApiModelProperty(value = "当前页")private Integer currentPage = 1;@ApiModelProperty(value = "展示数量")private Integer pageSize = 10;@ApiModelProperty(value = "总记录数")private Long count = 0L;@ApiModelProperty(value = "返回数据")private List<T> data = new ArrayList<>(10);}
  4. 响应封装工具

     小熙替换了自己项目的,替换成了 springMVC 的 ResponseEntity,也可以替换成自己项目的更适合项目环境
    

四. 代码 :

  1. 抽取封装类:

    package com.chengxi.datalom.utils.rest;import cn.hutool.core.bean.BeanUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.RequestEntity;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.client.HttpClientErrorException;
    import org.springframework.web.client.RestClientException;
    import org.springframework.web.client.RestTemplate;import java.net.URI;
    import java.util.*;
    import java.util.stream.Collectors;/*** 依赖方法封装** @author chengxi* @date 2020/5/30 21:00*/
    @Slf4j
    public abstract class AbstractExtractionRestUtil {/*** 抽取请求bean** @param appId* @param apiUrl* @param requestData* @param responseBeanClass* @param restTemplate* @param httpMethod* @param <T>* @param <R>* @return*/protected static <T, R> T requestMethodBodyBean(String appId, String apiUrl, R requestData, Class<T> responseBeanClass, RestTemplate restTemplate, HttpMethod httpMethod) {Object responseData = requestMethodBody(appId, apiUrl, requestData, restTemplate, httpMethod);if (responseData == null) {return null;}Map<String, Object> data = (Map<String, Object>) responseData;T responseInfoBean = null;try {responseInfoBean = BeanUtil.mapToBean(data, responseBeanClass, false);} catch (Exception e) {e.printStackTrace();log.error("类型转换异常,map投射Bean异常:{}", e);throw new ClassCastException("类型转换异常,map投射Bean异常");}return responseInfoBean;}/*** 抽取请求beanList** @param responseDataList* @param responseBeanClass* @param <T>* @param <R>* @return*/protected static <T, R> List<T> requestMethodBodyBeanList(Collection<Object> responseDataList, Class<T> responseBeanClass) {try {return responseDataList.stream().map(responseData -> {Map<String, Object> mapData = (Map<String, Object>) responseData;return BeanUtil.mapToBean(mapData, responseBeanClass, false);}).collect(Collectors.toList());} catch (Exception e) {e.printStackTrace();log.error("类型转换异常,map投射Bean异常:{}", e);throw new ClassCastException("类型转换异常,map投射Bean异常");}}/*** 抽取请求body** @param appId* @param apiUrl* @param requestData* @param restTemplate* @param httpMethod* @param <R>* @return*/protected static <R> Object requestMethodBody(String appId, String apiUrl, R requestData, RestTemplate restTemplate, HttpMethod httpMethod) {String url = urlCreat(appId, apiUrl);RequestEntity<R> requestEntity = null;if (requestData == null) {requestEntity = new RequestEntity<>(httpMethod, URI.create(url));} else {requestEntity = new RequestEntity<>(requestData, httpMethod, URI.create(url));}// 这里的object可以替换成自己封装的返回类(更符合项目环境),小熙分享时是把项目中的替换成了objectResponseEntity<Object> exchange = null;try {exchange = restTemplate.exchange(requestEntity, Object.class);} catch (HttpClientErrorException e) {e.getResponseBodyAsString();log.error("HttpClientErrorException:{}", e);throw new RestClientException(e.getResponseBodyAsString());} catch (RestClientException e) {e.printStackTrace();log.error("RestTemplate远程调用请求异常:{}", e);throw new RestClientException("RestTemplate远程调用请求异常");}if (exchange == null) {log.info("exchange == null");return null;} else if (exchange.getBody() == null) {log.info("exchange.getBody() == null");return null;}return exchange.getBody();}/*** 抽取响应体的集合** @param responseData* @param responseBeanClass* @param <T>* @return*/protected static <T> List<T> getResponseDataList(Object responseData, Class<T> responseBeanClass) {if (responseData == null) {return null;}if (responseData instanceof Collection) {Collection<Object> responseDataList = (Collection<Object>) responseData;return requestMethodBodyBeanList(responseDataList, responseBeanClass);} else if (responseData.getClass().isArray()) {List<Object> responseDataList = Arrays.asList(responseData);return requestMethodBodyBeanList(responseDataList, responseBeanClass);}throw new ClassCastException("返回类型不是单链集合");}/*** 创建Url** @param appId* @param apiUrl* @return*/protected static String urlCreat(String appId, String apiUrl) {return "http://" + appId + apiUrl;}}
  2. restTemplate工具类:

    package com.chengxi.datalom.utils.rest;import com.google.common.collect.Lists;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.http.HttpMethod;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RestTemplate;import java.util.*;/*** 程熙cjp:https://blog.csdn.net/weixin_41133233* <p>* resetTemplate自定义请求工具类* restTemplate 需要请求方注入,因为来自不同服务所以要携带一些自己的信息* 远程调用默认返回本项目中自定的ResponseVO类** @author chengxi* @date 2020/5/30 21:00*/
    @Slf4j
    @Component
    public class RestTemplateUtil extends AbstractExtractionRestUtil {/*** Get请求a* get请求如果需要携带body传输,请自定义一a个factory,扩展HttpComponentsClientHttpRequestFactory,并在RestTemplateConfig中指定此拓展** @param appId             服务id* @param apiUrl            访问路径* @param requestData       请求参数* @param responseBeanClass 返回bean的类型* @param restTemplate      注入的RestTemplate* @param <T>* @param <R>* @return*/public static <T, R extends Object> T requestGet(String appId, String apiUrl, R requestData, Class<T> responseBeanClass, RestTemplate restTemplate) {return restTemplate.getForObject(urlCreat(appId, apiUrl), responseBeanClass, requestData);}/*** Post请求** @param appId* @param apiUrl* @param requestData* @param responseBeanClass* @param restTemplate* @param <T>* @param <R>* @return 返回Bean*/public static <T, R> T requestBeanPost(String appId, String apiUrl, R requestData, Class<T> responseBeanClass, RestTemplate restTemplate) {return requestMethodBodyBean(appId, apiUrl, requestData, responseBeanClass, restTemplate, HttpMethod.POST);}/*** Post请求** @param appId* @param apiUrl* @param requestData* @param responseBeanClass* @param restTemplate* @param <T>* @param <R>* @return 返回List<Bean>*/public static <T, R> List<T> requestBeanListPost(String appId, String apiUrl, R requestData, Class<T> responseBeanClass, RestTemplate restTemplate) {Object responseData = requestMethodBody(appId, apiUrl, requestData, restTemplate, HttpMethod.POST);return getResponseDataList(responseData, responseBeanClass);}/*** Post请求** @param appId* @param apiUrl* @param requestData* @param responseBeanClass* @param restTemplate* @param <T>* @param <R>* @return 返回Page<List < Bean>>*/public static <T, R> PageVO<T> requestBeanListPageVoPost(String appId, String apiUrl, R requestData, Class<T> responseBeanClass, RestTemplate restTemplate) {Map<String, Object> responseMapData = null;try {Object responseData = requestMethodBody(appId, apiUrl, requestData, restTemplate, HttpMethod.POST);if (responseData == null) {return null;}responseMapData = (HashMap<String, Object>) responseData;} catch (Exception e) {e.printStackTrace();log.error("类型转换异常: 分页响应数据转换:{}", e);throw new ClassCastException("类型转换异常: 分页响应数据转换");}Object data = responseMapData.get("data");Integer currentPage = (Integer) responseMapData.get("currentPage");Integer pageSize = (Integer) responseMapData.get("pageSize");int count = (int) responseMapData.get("count");List<T> responseDataList = getResponseDataList(data, responseBeanClass);return new PageVO<T>(currentPage, pageSize, (long) count, responseDataList);}/*** Post请求** @param appId* @param apiUrl* @param requestData* @param restTemplate* @param <R>* @return 返回List(String)*/public static <R> List<String> requestStringListPost(String appId, String apiUrl, R requestData, RestTemplate restTemplate) {Object responseData = requestMethodBody(appId, apiUrl, requestData, restTemplate, HttpMethod.POST);if (responseData == null) {return null;}try {if (responseData instanceof List) {return (List<String>) responseData;} else if (responseData instanceof Set) {return new ArrayList<String>((Set) responseData);} else if (responseData instanceof String[]) {return Arrays.asList((String[]) responseData);} else if (responseData instanceof String) {return Lists.newArrayList((String) responseData);} else if (requestData instanceof Queue) {return (List<String>) responseData;} else if (requestData instanceof AbstractCollection) {return (List<String>) responseData;}} catch (ClassCastException e) {e.printStackTrace();log.error("类型转换异常,返回值转换为String类型异常:{}", e);throw new ClassCastException("类型转换异常,返回值转换为String类型异常");}throw new ClassCastException("返回数据类型不是String");}/*** Get请求  无参** @param appId* @param apiUrl* @param responseBeanClass* @param restTemplate* @param <T>* @return 返回bean*/public static <T> T requestGet(String appId, String apiUrl, Class<T> responseBeanClass, RestTemplate restTemplate) {return restTemplate.getForObject(urlCreat(appId, apiUrl), responseBeanClass);}/*** Post请求 无参** @param appId* @param apiUrl* @param responseBeanClass* @param restTemplate* @param <T>* @return 返回bean*/public static <T> T requestBeanPost(String appId, String apiUrl, Class<T> responseBeanClass, RestTemplate restTemplate) {return requestMethodBodyBean(appId, apiUrl, null, responseBeanClass, restTemplate, HttpMethod.POST);}}

五. 示例:

小熙写一段代码介绍下基本使用,其他方法同理:

  1. 服务调用方

    // 小熙列举其中之一的方法举例,其他同理
    // 第一个参数是服务id(服务名称),第二个参数是服务内的访问路径,第三个参数是请求参数对象,第四个参数是返回类型的class,第五个参数是restTemplate(依赖注入后入参)
    List<User> userList = RestTemplateUtil.requestBeanListPost("user-center", "/userController/selectUserByCondition", new SearchUserVO(), User.class, restTemplate);
    
  2. 服务提供方

    @PostMapping(value = "/selectUserByCondition")
    @ApiOperation(value = "通过条件查询用户,供远程调用")
    public ResponseEntity<List<User>> selectUserByCondition(SearchUserVO searchUserVO){List<User> userList = userService.list(Wrappers.<User>lambdaQuery().like(StringUtils.isNotEmpty(searchUserVO.getName()), User::getName, searchUserVO.getName()).eq(User::getAge, searchUserVO.getAge()));return new ResponseEntity<>(userList, HttpStatus.OK);
    }
    

六. 后语:

小熙写的是根据目前使用到的,大部分场景应该可以了,如果有其他场景可以拓展,大家可以发表些见解,感谢指正。

restTemplate封装工具类相关推荐

  1. JAVA——Okhttp封装工具类

    基本概念 OKhttp:一个处理网络请求的开源项目,是安卓端最火热的轻量级框架. Maven <!--OK HTTP Client--><dependency><grou ...

  2. android文件读取工具类,Android 下读取Assets Properties操作封装工具类

    Android 下读取Assets Properties操作封装工具类 发布时间:2018-06-03作者:laosun阅读(2081) 为了方便使用,首先创建BaseApplication类,如下所 ...

  3. 数据库MySQL基础---JDBC开发步骤--JDBC封装工具类--PreparedStatement实现CRUD操作

    JDBC简介 1.JDBC定义Java数据库连接(Java Database Connectivity,简称JDBC):是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询 ...

  4. JAVA之旅(五)——this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块...

    JAVA之旅(五)--this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块 周末收获颇多,继续学习 一.this关键字 用于区分局部变量和成员变量同名的情况 ...

  5. 如何调用封装工具类调用网上接口查询工作日

    如何调用封装工具类调用网上接口查询工作日 这里的编辑器是STS,用的springboot集成环境: 先引进pom.xml依赖包 <?xml version="1.0" enc ...

  6. 四、EasyExcel实现Excel读写,封装工具类

    在项目中,我们经常用到EasyExcel框架实现:对Excel文件的读写操作.为了方便后续其他项目中的使用,将对Excel文件的读写操作,封装成工具类. 一.EasyExcel实现Excel读写,封装 ...

  7. 仿京东APP分类页面(mvp模式+OkHttp封装工具类+拦截器+弱引用回收)

    仿京东APP分类页面: 添加依赖 compile 'com.android.support:recyclerview-v7:24.0.0' compile 'com.google.code.gson: ...

  8. Spring Boot 整合 SpringDataNeo4j 并封装工具类解析PathValue

    Spring Boot 整合 SpringDataNeo4j 并封装工具类解析PathValue 一.Neo4j 二.Neo4j客户端浏览器 三.maven依赖 四.节点/关系映射 1.NodePer ...

  9. MySQL JDBC常用知识,封装工具类,时区问题配置,SQL注入问题

    JDBC JDBC介绍 Sun公司为了简化开发人员的(对数据库的统一)操作,提供了(Java操作数据库的)规范,俗称JDBC,这些规范的由具体由具体的厂商去做 对于开发人员来说,我们只需要掌握JDBC ...

  10. jdbc封装工具类代码_JDBC的使用-JDBC(3)

    光有理论,没有实践是不行的,本篇文章就是介绍JDBC如何使用. 本文知识点分布如下: 下载数据库驱动 创建项目添加驱动 通过 Statement 向表中插入数据 通过 Statement 对象修改表中 ...

最新文章

  1. python 获取程序运行时间
  2. excel调用python编程-使用Python对Excel进行读写操作
  3. 在.net下使用WebBrower控件时屏蔽弹出新窗口
  4. 相对定位android,appium相对位置定位元素----父节点/兄弟节点定位
  5. VTK:IO之ConvertFile
  6. jQuery实现一个图片左右滚动
  7. SCPPO(九):性能优化之停工装置按照开工装置更新价格
  8. object对象进行深拷贝
  9. C语言用冒泡法对数组元素降序,冒泡法排序c语言
  10. Linux之mmap
  11. Tableau 自定义调色板及应用全流程讲解【保姆级】
  12. 手机图形计算器matlab,Mathlab图形计算器下载
  13. Wide Deep模型
  14. pytorch seq2seq模型中加入teacher_forcing机制
  15. java横向导出excel_JavaWeb POI 导出Excel
  16. 剑指Offer66题之每日6题 - 第六天
  17. 第一周-机器学习监督学习-无监督学习
  18. python爬取蚂蜂窝帖子图片
  19. 那些年,我们一起写过的单例模式
  20. pic单片机使用printf函数

热门文章

  1. 【2020 Java基础快速学习路线】写了很久,这是一份最适合普通大众、非科班的路线
  2. DataSheet IFI9486
  3. 2020年陕西省高等职业院校技能大赛信息安全管理与评估赛项竞赛手册
  4. 2021湖北技能高考成绩时间查询,2020湖北技能高考成绩查询时间
  5. 公众号七种有效的引流方式
  6. 记win10家庭版系统C:\Users用户名中文改英文 详细教程
  7. 回溯法——旅行商(TSP)问题
  8. 混沌理论(Chaos Theory)
  9. Win11麦克风有回音怎么消除 Win11麦克风回声怎么调
  10. ant design + react带有二级导航菜单自动生成