httpclient工具类(支持泛型转换)

httpclient工具类

1、网上搜到的httpclient工具类的问题:

1.1、如下图我们都能够发现这种封装的问题:

  • 代码繁杂、充斥了很多重复性代码
  • 返回值单一,无法拿到对应的Java Bean对象、List、Page对象集合
  • 实际场景中会对接大量第三方的OPEN API,下述方法的扩展性差

在这里插入图片描述

1.2、简洁调用方式演示

本文基于上述问题,通过设计模式、泛型、JSON工具类的方式进行了封装,得到了下述更方便、更简洁的http请求调用方式

Entity params = new Entity();
params.setUrl("/common/postJson");
 Map<String, Object> map = new HashMap<>();
map.put("userId", "13277887788");
map.put("companyId", "87037827534cf");
params.setParams(map);

// 返回对象集合
List<AppEntity> appEntity = thirdHttpProcessorFactory
	.doGetReturnList(ThirdSystemEnum.ION, params, AppEntity.class, false);
// 返回分页对象
IPage<AppEntity> appEntity = thirdHttpProcessorFactory
	.doGetReturnPage(ThirdSystemEnum.ION, params, AppEntity.class, false);
// 返回String类型
String result = thirdHttpProcessorFactory
	.doGetReturnBean(ThirdSystemEnum.ION, params, String.class, false);
// 返回指定的对象
AppEntity appEntity = thirdHttpProcessorFactory
	.doGetReturnBean(ThirdSystemEnum.ION, params, AppEntity.class, false);

/**
 * 查询资产详情列表
 */
@GetMapping("/detailList")
public AjaxResult detailList(AssetDetailInfoVo vo) throws Exception {
    Entity entity = new Entity("/assetInfo/detailList", BeanUtil.beanToMap(vo));
    IPage<AssetDetailInfoRsp> list = thirdHttpProcessorFactory
    .doGetReturnPage(ThirdSystemEnum.ION, entity, AssetDetailInfoRsp.class, false);
    return AjaxResult.success(list);
}
        

1.3、 目录结构

在这里插入图片描述

2、引入的maven仓库

 <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
	 <version>2.14.2</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.16</version>
</dependency>
  • ThirdHttpProcessorFactory:存储不同三方平台的处理期
  • ThirdHttpProcessor:定义通用的接口
  • AbstractThirdHttpProcessor:定义公共的处理逻辑
  • IonHttpProcessor:定义各对接平台的差异性逻辑
  • CommonResponse:调用第三方通用返回值处理
  • Entity:入参
  • PageEntity:分页实体
  • ThirdSystemEnum:定义三方平台的枚举

3、代码实现

3.1、获取不同第三方处理器的工厂ThirdHttpProcessorFactory

3.1.1、获取单例处理器的工厂实现
import lombok.experimental.Accessors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ke
 * Created by on  2023-10-27 15:23
 */
@Component
@Accessors(chain = true)
public class ThirdHttpProcessorFactory {

    @Autowired
    private List<ThirdHttpProcessor> thirdHttpProcessors;

    private Map<String, ThirdHttpProcessor> thirdHttpProcessorMap;

    @PostConstruct
    public void init() {
        if (CollectionUtils.isEmpty(thirdHttpProcessors)) {
            return;
        }
        thirdHttpProcessorMap = new HashMap<>(8);
        for (ThirdHttpProcessor processor : thirdHttpProcessors) {
            thirdHttpProcessorMap.put(processor.getType().getCode(), processor);
        }
    }

    private ThirdHttpProcessor getThirdHttpProcessor(String type) {
        ThirdSystemEnum thirdSystemEnum = ThirdSystemEnum.getByCode(type);
        if (null == thirdSystemEnum) {
            throw new ServiceException("三方OpenApi尚未配置,无法进行请求");
        }
        return thirdHttpProcessorMap.get(type);
    }


   
    /**
     * http get请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return T              返回数据对象
     * @throws Exception 业务执行异常
     */
    public <T> T doGetReturnBean(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doGetReturnBean(entity, tClass);
        } catch (Exception e) {
            throwException(e, isThrow);
        }
        return null;
    }

    private void throwException(Exception e, boolean isThrow) throws Exception {
        if (isThrow) {
            throw e;
        }
    }

    /**
     * http post请求,入参支持application/x-www-form-urlencoded 请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return T              返回数据对象
     * @throws Exception 业务执行异常
     */
    public <T> T doPostReturnBean(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostReturnBean(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return null;
    }

    /**
     * http post请求,入参支持application/json请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return T              返回数据对象
     * @throws Exception 业务执行异常
     */
    public <T> T doPostJsonReturnBean(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostJsonReturnBean(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return null;
    }

    /**
     * http get请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return List<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> List<T> doGetReturnList(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doGetReturnList(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return Lists.newArrayList();
    }

    /**
     * http get请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return IPage<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> IPage<T> doGetReturnPage(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doGetReturnPage(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return new Page<T>(entity.getPageNum(), entity.getPageSize(), 0);
    }

    /**
     * http post请求,入参支持application/x-www-form-urlencoded 请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return List<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> List<T> doPostReturnList(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostReturnList(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return Lists.newArrayList();
    }

    /**
     * http post请求,入参支持application/json请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return List<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> List<T> doPostJsonReturnList(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostJsonReturnList(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return Lists.newArrayList();
    }
}
3.1.2、获取多实例处理器的工厂实现
/**
 * Dans.com Inc. Copyright (c) 2011-2020 All Rights Reserved
 */
package com.ionrocking.platform.tripartite;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import lombok.experimental.Accessors;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ke
 * Created by on  2023-10-27 15:23
 */
@Component
@Accessors(chain = true)
public class ThirdHttpProcessorFactory implements ApplicationContextAware {

    @Autowired
    private List<ThirdHttpProcessor> thirdHttpProcessors;

    private Map<String, ThirdHttpProcessor> thirdHttpProcessorMap;

    private ApplicationContext context = null; 

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    private ThirdHttpProcessor getThirdHttpProcessor(String type) {
        Map<String, ThirdHttpProcessor> map = context.getBeansOfType(ThirdHttpProcessor.class);
        ThirdSystemEnum thirdSystemEnum = ThirdSystemEnum.getByCode(type);
        if (null == thirdSystemEnum) {
            throw new ServiceException("三方OpenApi尚未配置,无法进行请求");
        }
        for (Map.Entry<String, ThirdHttpProcessor> httpProcessorEntry : map.entrySet()) {
            if (thirdSystemEnum == httpProcessorEntry.getValue().getType()) {
                return httpProcessorEntry.getValue();
            }
        }
        throw new ServiceException("三方OpenApi尚未配置,无法进行请求");
    }


    /**
     * http get请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return T              返回数据对象
     * @throws Exception 业务执行异常
     */
    public <T> T doGetReturnBean(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doGetReturnBean(entity, tClass);
        } catch (Exception e) {
            throwException(e, isThrow);
        }
        return null;
    }

    private void throwException(Exception e, boolean isThrow) throws Exception {
        if (isThrow) {
            throw e;
        }
    }

    /**
     * http post请求,入参支持application/x-www-form-urlencoded 请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return T              返回数据对象
     * @throws Exception 业务执行异常
     */
    public <T> T doPostReturnBean(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostReturnBean(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return null;
    }

    /**
     * http post请求,入参支持application/json请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return T              返回数据对象
     * @throws Exception 业务执行异常
     */
    public <T> T doPostJsonReturnBean(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostJsonReturnBean(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return null;
    }

    /**
     * http get请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return List<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> List<T> doGetReturnList(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doGetReturnList(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return Lists.newArrayList();
    }

    /**
     * http get请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return IPage<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> IPage<T> doGetReturnPage(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doGetReturnPage(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return new Page<T>(entity.getPageNum(), entity.getPageSize(), 0);
    }

    /**
     * http post请求,入参支持application/x-www-form-urlencoded 请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return List<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> List<T> doPostReturnList(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostReturnList(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return Lists.newArrayList();
    }

    /**
     * http post请求,入参支持application/json请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return List<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> List<T> doPostJsonReturnList(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass, boolean isThrow) throws Exception {
        try {
            return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostJsonReturnList(entity, tClass);
        } catch (Exception e) {
            throwException(e, Boolean.TRUE.equals(isThrow));
        }
        return Lists.newArrayList();
    }
}

3.2、http请求处理的接口ThirdHttpProcessor

import java.util.List;

/**
 * 追踪事件处理器
 *
 * @author ke
 * Created by on  2023-06-20 15:23
 */
public interface ThirdHttpProcessor {

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return T
     * @throws Exception 业务执行异常
     */
    <T> T doGetReturnBean(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return
     * @throws Exception 业务执行异常
     */
    <T> T doPostReturnBean(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return
     * @throws Exception 业务执行异常
     */
    <T> T doPostJsonReturnBean(Entity entity, Class<T> tClass) throws Exception;
    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return T
     * @throws Exception 业务执行异常
     */
    <T> List<T> doGetReturnList(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return
     * @throws Exception 业务执行异常
     */
    <T> List<T> doPostReturnList(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return
     * @throws Exception 业务执行异常
     */
    <T> List<T> doPostJsonReturnList(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 获取事件类型
     *
     * @return
     */
    ThirdSystemEnum getType();
}

3.3、通用逻辑处理的抽象类AbstractThirdHttpProcessor

  • 如在通过http client发起HTTP请求时,除了请求头requestHeader、请求入参requestBody不同,其他逻辑都是一样的,则可以进行公共代码的抽取
  • 如果存在特殊的逻辑处理,则可以在子类中重写父类的方法
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.K;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author ke
 * @Date 2023/10/27
 */
@Slf4j
@Component
public abstract class AbstractThirdHttpProcessor implements ThirdHttpProcessor {

    @Resource
    protected RedisService redisService;

    @Override
    public <T> List<T> doGetReturnList(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        log.info("domainName:{},requestParameter:{},requestHead:{}", sysNacosConfig.getIonRequestUrl(), JSONUtil.toJsonStr(entity), JSONUtil.toJsonStr(requestHead));
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createGet(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .form(requestBody)
                .execute()
                .body();
        return toList(result, tClass, entity);
    }

    @Override
    public <T> List<T> doPostReturnList(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createPost(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .form(requestBody)
                .execute()
                .body();
        return toList(result, tClass, entity);
    }

    @Override
    public <T> List<T> doPostJsonReturnList(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createPost(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .body(JSONUtil.toJsonStr(requestBody))
                .execute()
                .body();
        return toList(result, tClass, entity);
    }

    /**
     * 转换http请求查询结果,不同也无妨返回的结构不一样
     * 此处可以拿到调用三方返回的结果集转成通用的返回结果
     * @param httpResult
     * @param entity
     * @param <T>
     * @return
     */
    public abstract <T> CommonResponse<T> covertHttpResult(String httpResult, Entity entity);

    public <T> T toBean(String result, Class<T> tClass, Entity entity) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        CommonResponse<Object> response = covertHttpResult(result, entity);
        return objectMapper.readValue(response.getData().toString(), tClass);
    }

    public <T> List<T> toList(String httpResult, Class<T> tClass, Entity entity) throws JsonProcessingException {
        List<T> data = new ArrayList<>();
        CommonResponse<List<Object>> response = covertHttpResult(httpResult, entity);
        for (Object o : response.getData()) {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            data.add(objectMapper.readValue(o.toString(), tClass));
        }
        return data;
    }

    public <T> IPage<T> toPage(String httpResult, Class<T> tClass, Entity entity) throws JsonProcessingException {
        List<T> data = new ArrayList<>();
        IPage<T> page = new Page<>();
        CommonResponse<List<Object>> response = covertHttpResult(httpResult, entity);
        if (CollUtil.isNotEmpty(response.getData())) {
            for (Object o : response.getData()) {
                ObjectMapper objectMapper = new ObjectMapper();
                objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                data.add(objectMapper.readValue(o.toString(), tClass));
            }
        }
        page.setTotal(response.getTotal());
        page.setRecords(data);
        return page;
    }

    @Resource
    protected SysNacosConfig sysNacosConfig;

    protected static final int CODE = 200;

    @Override
    public <T> T doGetReturnBean(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createGet(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .form(requestBody)
                .execute()
                .body();
        return toBean(result, tClass, entity);
    }

    /**
     * 执行
     *
     * @return
     */
    @Override
    public <T> T doPostReturnBean(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createPost(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .form(requestBody)
                .execute()
                .body();
        return toBean(result, tClass, entity);
    }

    @Override
    public <T> T doPostJsonReturnBean(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createPost(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .body(JSONUtil.toJsonStr(requestBody))
                .execute()
                .body();
        return toBean(result, tClass, entity);
    }

    @Override
    public <T> IPage<T> doGetReturnPage(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createGet(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .form(requestBody)
                .execute()
                .body();
        return toPage(result, tClass, entity);
    }

    /**
     * 构造请求头
     *
     * @param entity
     * @return
     */
    public abstract Map<String, String> constructRequestHead(Entity entity);

    /**
     * 构造请求体
     *
     * @param entity
     * @return
     */
    public Map<String, Object> constructRequestBody(Entity entity) {
        if (CharSequenceUtil.isBlank(entity.getUrl())) {
            throw new ServiceException("请求路径不能为空");
        }
        if (null == entity) {
            return null;
        }
        return entity.getParams();
    }

    /**
     * 生成错误信息日志
     *
     * @param thirdSystemEnum
     * @param msg
     * @return
     */
    public String generalErrorLog(ThirdSystemEnum thirdSystemEnum, String url, String params, String msg) {
        String errorMsg = StrUtil.format("调用{}开发平台接口:{},入参:{} 失败,失败原因:{}", thirdSystemEnum.getName(), url, params, msg);
        log.error(errorMsg);
        return errorMsg;
    }

    /**
     * 生成错误信息日志
     *
     * @param thirdSystemEnum
     * @param msg
     * @return
     */
    public String generalErrorLogNoParams(ThirdSystemEnum thirdSystemEnum, String url, String msg) {
        String errorMsg = StrUtil.format("调用{}开发平台接口:{} 失败,失败原因:{}", thirdSystemEnum.getName(), url, msg);
        log.error(errorMsg);
        return errorMsg;
    }
}


3.4、第三方非通用逻辑处理类IonHttpProcessor

  • 比如此处对接的xx公司需要进行access_token获取及验证,然后将access_token放在请求头中
package com.ionrocking.platform.tripartite.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author ke
 * @Date 2023/10/27
 */
@Slf4j
@Component
public class IonHttpProcessor extends AbstractThirdHttpProcessor {

    private static final String ACCESS_TOKEN_URL = "/token/getAccessToken";


    @Override
    public <R> CommonResponse<R> covertHttpResult(String httpResult, Entity entity) {
        IonResponse<R> response = JSONUtil.toBean(httpResult, IonResponse.class);
        if (CODE != response.getCode()) {
            generalErrorLog(getType(), entity.getUrl(), JSONUtil.toJsonStr(entity), response.getMsg());
            throw new ServiceException(generalErrorLogNoParams(getType(), entity.getUrl(), response.getMsg()));
        }
        if (null == response.getData()) {
            return new CommonResponse<>(response.getRows(), response.getTotal());
        }
        return new CommonResponse<>(response.getData(), 0);
    }

    @Override
    public Map<String, String> constructRequestHead(Entity entity) {
        Map<String, String> header = new HashMap<>(2);
        // 存储ION的access_token,降低获取频率
        String key = SysConstants.ION_ACCESS_TOKEN_PREFIX + sysNacosConfig.getIonRequestAppId();
        Boolean hasKey = redisService.hasKey(key);
        if (Boolean.TRUE.equals(hasKey)) {
            String accessToken = redisService.getCacheObject(key).toString();
            header.put(SysConstants.ACCESS_TOKEN_KEY, accessToken);
        } else {
            Map<String, Object> params = new HashMap<>(4);
            params.put("appId", sysNacosConfig.getIonRequestAppId());
            params.put("appSecret", sysNacosConfig.getIonRequestAppSecret());
            String result = HttpUtil.get(sysNacosConfig.getIonRequestUrl() + ACCESS_TOKEN_URL, params);
            log.info("/token/getAccessToken ==> params:{}, result:{}", JSONUtil.toJsonStr(params), result);
            if (CharSequenceUtil.isEmpty(result)) {
                return null;
            }
            TypeReference<IonResponse<Map<String, Object>>> typeRef = new TypeReference<IonResponse<Map<String, Object>>>() {
            };
            IonResponse<Map<String, Object>> response = JSONUtil.toBean(result, typeRef, false);
            if (CODE == response.getCode() && null != response.getData()) {
                if (response.getData().containsKey(SysConstants.ACCESS_TOKEN_KEY)) {
                    String accessToken = response.getData().get(SysConstants.ACCESS_TOKEN_KEY).toString();
                    Long expireTime = Long.parseLong(response.getData().get(SysConstants.ACCESS_TOKEN_EXPIRE_TIME).toString());
                    header.put(SysConstants.ACCESS_TOKEN_KEY, accessToken);
                    redisService.setCacheObject(key, accessToken, expireTime, TimeUnit.SECONDS);
                }
            } else {
                throw new ServiceException(super.generalErrorLogNoParams(getType(), ACCESS_TOKEN_URL, response.getMsg()));
            }
        }
        return header;
    }

    @Override
    public ThirdSystemEnum getType() {
        return ThirdSystemEnum.ION;
    }
}

如果需要获取多例处理器对象,需要在类上添加注解 @Scope(“prototype”)

3.5、枚举类ThirdSystemEnum

  • 区分不同的平台,根据枚举获取不同的实现类

import org.apache.commons.lang3.StringUtils;

/**
 * @author ke
 * @Date 2023/10/27
 */
public enum ThirdSystemEnum {
    /**
     * XX科技公司
     */
    ION("ion", "xx科技");

    private final String code;

    private final String name;

    public String getName() {
        return this.name;
    }


    public String getCode() {
        return this.code;
    }

    ThirdSystemEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public static ThirdSystemEnum getByCode(String code) {
        if (StringUtils.isEmpty(code)) {
            return null;
        }
        for (ThirdSystemEnum codeEnum : values()) {
            if (code.equals(codeEnum.getCode())) {
                return codeEnum;
            }
        }
        return null;
    }
}

3.6、第三方返回格式对象IonResponse


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author ke
 * @Date 2023/10/27
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class IonResponse<T> implements Serializable {

    private static final long serialVersionUID = -8741972144218822267L;
    private int code;
    /**
     * 消息
     */
    private String msg;
    /**
     * 数据
     */
    private T data;
    /**
     * 总记录数
     */
    private long total;
}

3.7、处理器入参对象Entity

  • 此处定义请求的URL和请求的参数

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Map;

/**
 * @author ke
 * @Date 2023/10/27
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Entity extends PageEntity{

    private static final long serialVersionUID = -6083780287057302816L;

    private String url;

    /**
     * 参数
     */
    private Map<String, Object> params;
}


/**
 * 分页实体基类
 * @author ke
 * @Date 2023/11/6
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageEntity implements Serializable {

    private Integer pageNum = 1;

    private Integer pageSize = 10;
}

3.8 通用三方接口调用返回值接收对象

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * 调用第三方通用返回结果处理接收对象
 * @author ke
 * @Date 2023/11/24
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResponse<T> implements Serializable {

    private static final long serialVersionUID = 5955491924347403636L;

    private T data;

    private long total;
}

3.9、Nacos配置

  • Nacos中一般存放一些第三方的请求域名、鉴权的appId、appSecret等
tripartite-platform:
  ion:
    request:
      url: http://localhost:8080/api/
      appId: YodeqWwp
      appSecret: 87037827534cf848a570fae3c93a2469fa0262935af531dddfe7a52ae7f98f41

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * nacos配置信息
 * @author ke
 * @Date 2023/9/20
 */
@Component
public class SysNacosConfig {


    @Value("${upload.path}")
    private String uploadPath;

    @Value("${tripartite-platform.ion.request.url}")
    private String ionRequestUrl;

    @Value("${tripartite-platform.ion.request.appId}")
    private String ionRequestAppId;

    @Value("${tripartite-platform.ion.request.appSecret}")
    private String ionRequestAppSecret;

    public String getUploadPath() {
        return uploadPath;
    }

    public String getIonRequestUrl() {
        return ionRequestUrl;
    }

    public String getIonRequestAppId() {
        return ionRequestAppId;
    }

    public String getIonRequestAppSecret() {
        return ionRequestAppSecret;
    }
}

测试

调用三方定义的返回值对象


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotBlank;

/**
 * @author ke
 * @Date 2023/10/26
 */

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class AppEntity {
    private long id;

    private String appId;

    @NotBlank(message = "应用名称不能为空")
    private String appName;

    private String appSecret;

    private String accessToken;

    private Integer isFlag;
}
测试Controller
@RestController
@RequestMapping("/test")
public class Test {
    
    @Resource
    private SysNacosConfig sysNacosConfig;
    
    @Resource
    private ThirdHttpProcessorFactory thirdHttpProcessorFactory;
    
    @ResponseBody
    @RequestMapping(value = "/get")
    public AjaxResult get() throws Exception extends BaseController  {
        Entity params = new Entity();
        params.setUrl("/common/get");
        String result = thirdHttpProcessorFactory.doGetReturnBean(ThirdSystemEnum.ION, params, String.class);
        return AjaxResult.success(result);
    }


    @ResponseBody
    @RequestMapping(value = "/list")
    public AjaxResult list() throws Exception {
        Entity params = new Entity();
        params.setUrl("/common/list");
        List<AppEntity> appEntity = thirdHttpProcessorFactory.doGetReturnList(ThirdSystemEnum.ION, params, AppEntity.class);
        return AjaxResult.success(appEntity);
    }

    @ResponseBody
    @RequestMapping(value = "/postJson")
    public AjaxResult postJson() throws Exception {
        Entity params = new Entity();
        params.setUrl("/common/postJson");
        Map<String, Object> map = new HashMap<>();
        map.put("appId", "YodeqWwp");
        map.put("appSecret", "87037827534cf848a570fae3c93a2469fa0262935af531dddfe7a52ae7f98f41");
        params.setParams(map);
        List<AppEntity> list = thirdHttpProcessorFactory.doPostJsonReturnList(ThirdSystemEnum.ION, params, AppEntity.class);
		return AjaxResult.success(list);
    }
    /**
     * 分页查询
     */
    @GetMapping("/pageAppInfo")
    public AjaxResult pageAppInfo(AppageVo vo) throws Exception {
        Entity entity = new Entity("/common/pageAppInfo", BeanUtil.beanToMap(vo));
        IPage<AppEntity> list = thirdHttpProcessorFactory.doGetReturnPage(ThirdSystemEnum.ION, entity, AppEntity.class, false);
        return AjaxResult.success(list);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值