restTemplate封装工具类

一. 前言 :

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

二. 视图:

展示图:
在这里插入图片描述

三. 依赖 :

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

  1. 糊涂工具坐标

    	    
            
                cn.hutool
                hutool-all
                5.0.7
            
    
  2. 谷歌工具坐标

    		
            
                com.google.code.gson
                gson
                2.8.5
            
    
  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 {
    
        @ApiModelProperty(value = "当前页")
        private Integer currentPage = 1;
    
        @ApiModelProperty(value = "展示数量")
        private Integer pageSize = 10;
    
        @ApiModelProperty(value = "总记录数")
        private Long count = 0L;
    
        @ApiModelProperty(value = "返回数据")
        private List data = new ArrayList<>(10);
    
    }
    
    
  4. 响应封装工具

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

四. 代码 :

  1. restTemplate工具类:

    package com.chengxi.datalom.utils.rest;
    
    import com.baomidou.mybatisplus.extension.api.R;
    import com.chengxi.datalom.po.User;
    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
     *
     * 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 requestDate    请求参数
         * @param responseBeanClass      返回bean的类型
         * @param restTemplate   注入的RestTemplate
         * @param 
         * @param 
         * @return
         */
        public static  T requestGet(String appId, String apiUrl, R requestDate, Class responseBeanClass, RestTemplate restTemplate){
    
            return restTemplate.getForObject(urlCreat(appId, apiUrl),responseBeanClass,requestDate);
        }
    
        /**
         * Post请求
         * @param appId
         * @param apiUrl
         * @param requestDate
         * @param responseBeanClass
         * @param restTemplate
         * @param 
         * @param 
         * @return                      返回Bean
         */
        public static  T requestBeanPost(String appId, String apiUrl, R requestDate, Class responseBeanClass, RestTemplate restTemplate){
    
            return requestMethodBodyBean(appId, apiUrl, requestDate, responseBeanClass, restTemplate, HttpMethod.POST);
        }
    
        /**
         * Post请求
         * @param appId
         * @param apiUrl
         * @param requestDate
         * @param responseBeanClass
         * @param restTemplate
         * @param 
         * @param 
         * @return                      返回List
         */
        public static  List requestBeanListPost(String appId, String apiUrl, R requestDate, Class responseBeanClass, RestTemplate restTemplate){
    
            Object responseDate = requestMethodBody(appId, apiUrl, requestDate, restTemplate, HttpMethod.POST);
    
            return getResponseDateList(responseDate, responseBeanClass);
        }
    
        /**
         * Post请求
         * @param appId
         * @param apiUrl
         * @param requestDate
         * @param responseBeanClass
         * @param restTemplate
         * @param 
         * @param 
         * @return                      返回Page>
         */
        public static  PageVO requestBeanListPageVoPost(String appId, String apiUrl, R requestDate, Class responseBeanClass, RestTemplate restTemplate){
    
            Map responseMapData = null;
            Object responseData =  requestMethodBody(appId, apiUrl, requestDate, restTemplate, HttpMethod.POST);
            if (responseData == null) {
                return null;
            }
            try {
            	responseMapData = (HashMap) 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 responseDateList = getResponseDateList(data, responseBeanClass);
            return new PageVO(currentPage, pageSize, (long)count, responseDateList);
        }
    
        /**
         * Post请求
         * @param appId
         * @param apiUrl
         * @param requestDate
         * @param restTemplate
         * @param 
         * @return                       返回List(String)
         */
        public static  List requestStringListPost(String appId, String apiUrl, R requestDate, RestTemplate restTemplate){
            Object responseDate  = requestMethodBody(appId, apiUrl, requestDate, restTemplate, HttpMethod.POST);
            if (responseDate == null) {
                return null;
            }
    
            try {
                if (responseDate instanceof List) {
                    return (List) responseDate;
                }else if (responseDate instanceof Set) {
                    return new ArrayList((Set)responseDate);
                }else if (responseDate instanceof String[]) {
                    return Arrays.asList((String[]) responseDate);
                }else if (responseDate instanceof String) {
                    return Lists.newArrayList((String) responseDate);
                }else if (requestDate instanceof Queue) {
                    return (List) responseDate;
                }else if (requestDate instanceof AbstractCollection) {
                    return (List) responseDate;
                }
            } 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 
         * @return                       返回bean
         */
        public static  T requestGet(String appId, String apiUrl, Class responseBeanClass, RestTemplate restTemplate){
    
            return restTemplate.getForObject(urlCreat(appId, apiUrl),responseBeanClass);
        }
    
        /**
         * Post请求 无参
         * @param appId
         * @param apiUrl
         * @param responseBeanClass
         * @param restTemplate
         * @param 
         * @return                       返回bean
         */
        public static  T requestBeanPost(String appId, String apiUrl, Class responseBeanClass, RestTemplate restTemplate){
    
            return requestMethodBodyBean(appId, apiUrl, null, responseBeanClass, restTemplate, HttpMethod.POST);
        }
    
    }
    
    
  2. 抽取封装类:

    package com.chengxi.datalom.utils.rest;
    
    import cn.hutool.core.bean.BeanUtil;
    import com.google.common.collect.Lists;
    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 requestDate
         * @param responseBeanClass
         * @param restTemplate
         * @param httpMethod
         * @param 
         * @param 
         * @return
         */
        protected static  T requestMethodBodyBean(String appId, String apiUrl, R requestDate, Class responseBeanClass, RestTemplate restTemplate, HttpMethod httpMethod){
    
            Object responseDate  = requestMethodBody(appId, apiUrl,requestDate,restTemplate,httpMethod);
            if (responseDate == null) {
                return null;
            }
            Map data = (Map) responseDate;
    
            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 responseDateList
         * @param responseBeanClass
         * @param 
         * @param 
         * @return
         */
        protected static  List requestMethodBodyBeanList(List responseDateList, Class responseBeanClass) {
    
            try {
                return responseDateList.stream()
                        .map(m -> {
                            Map data = (Map) m;
    
                            return BeanUtil.mapToBean(data, 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 requestDate
         * @param restTemplate
         * @param httpMethod
         * @param 
         * @return
         */
        protected static  Object requestMethodBody(String appId, String apiUrl, R requestDate, RestTemplate restTemplate, HttpMethod httpMethod){
    
            String url = urlCreat(appId, apiUrl);
            RequestEntity requestEntity = null;
            if (requestDate == null) {
                requestEntity = new RequestEntity<>(httpMethod, URI.create(url));
            }else {
                requestEntity = new RequestEntity<>(requestDate, httpMethod, URI.create(url));
            }
    
            // 这里的object可以替换成自己封装的返回类(更符合项目环境),小熙分享时是把项目中的替换成了object
            ResponseEntity 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 responseDate
         * @param responseBeanClass
         * @param 
         * @return
         */
        protected static List getResponseDateList(Object responseDate, Class responseBeanClass){
    
            if (responseDate == null) {
                return null;
            }
            if (responseDate instanceof List) {
                List responseDateList = (List) responseDate;
    
                return requestMethodBodyBeanList(responseDateList, responseBeanClass);
            }else if (responseDate instanceof Set) {
                Set responseDateSet = (Set) responseDate;
                List responseDateList = Lists.newArrayList(responseDateSet);
    
                return requestMethodBodyBeanList(responseDateList, responseBeanClass);
            } else if (responseDate.getClass().isArray()) {
                List responseDateList = Arrays.asList(responseDate);
    
                return requestMethodBodyBeanList(responseDateList, responseBeanClass);
            }
    
            throw new ClassCastException("返回类型不是单链集合");
        }
    
        /**
         * 创建Url
         * @param appId
         * @param apiUrl
         * @return
         */
        protected static String urlCreat(String appId, String apiUrl){
            return  "http://" + appId + apiUrl;
        }
    
    }
    
      
       
      

    五. 示例:

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

    1. 服务调用方

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

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

    六. 后语:

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

    你可能感兴趣的:(工具类,Swagger,MyBatis,Plus,RestTemplate)