自定义springboot组件--统一封装http客户端实现

http是第三方接口调用的常用工具,该组件通过对常见的http客户端工具进行统一的整合,参考了feign的上下文和springmvc的拦截器等相关设计思路,设计了相应的Context用于对请求上下文的相关配置进行统一的配置,避免客户端配置混乱配置,保证了项目的统一配置,并内置了相应拦截器,用于客户端自定义相关的业务逻辑,比如:通过模仿feign的拦截器,解决了feig三方接口调用时无token的尴尬.

一 基本原理

在这里插入图片描述

  • 客户端发起http调用时,通过请求执行器,执行底层请求逻辑
  • 从请求的上下文中获得相应编码器,对body进行统一的序列化处理
  • 获得相应的前置处理器,执行自定义的业务前置处理(如token等公用参数的绑定)
  • 调用httprequestclient执行http请求(更具项目的自身需求,配置相应的客户端,默认为:JDK HttpURLConnection)
  • 请求发生异常,执行requestExceptionHandler中handler逻辑
  • 解析当前响应状态码,状态码不为200执行responseErrorHandler逻辑
  • 根据当前请求是否配置相应的响应前置处理器,做响应前置处理,没有直接通过解码器反序列化后相应当前请求的数据

二 客户端调用

2.1 根据项目的实际需求配置核心参数

详见源码具体配置
在这里插入图片描述

2.2 根据项目的实际需求选择相应的http客户端

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
默认http客户端
在这里插入图片描述

2.3 引入相应的组件

 <dependency>
            <groupId>com.cncloud</groupId>
            <artifactId>shell-platform-common-http-client</artifactId>
 </dependency>

2.4 bean方式调用

@RestController
@RequestMapping("/client")
@Slf4j
public class HttpClientController {

    @Autowired
    private HttpRequestExecutor httpRequestExecutor;

    public static final String LOGIN_URL = "https://develop.shequtalk.com/auth/oauth/token";

    public static final String GET_URL = "https://develop.shequtalk.com/admin/user/getUserListByDept";



    @PostMapping("/testPost")
    @Inner(value = false)
    public void testPost(){
        HttpRequest request = getLoginRequest();
        final R result = httpRequestExecutor.execute(request);
        log.info("login result : {}",result);
    }

    @GetMapping("/testGet")
    @Inner(value = false)
    public void testGet(){
        HttpRequest request = new BasicRequestBuilder(GET_URL)
                .header("tenant-id", "6054656364413952")
                .header("authorization", "Bearer 8350ebce-1f98-41e3-a30f-69f4f6702119")
                .method(RequestMethod.GET)
                .query("sysDeptId", "6054656376194048")
                .query("current", 1)
                .query("size", 10)
                .resultType(R.class)
                .build();
        R result = httpRequestExecutor.execute(request);
        log.info("query result: {}",result);
    }
    private HttpRequest getLoginRequest() {
        HashMap<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("username","szs");
        bodyMap.put("password","rKu1/348LvKp0rsVC06eCA==");
        bodyMap.put("grant_type","password");

        HttpRequest request = new BodyRequestBuilder<>(LOGIN_URL)
                .header("tenant-id", "6054656364413952")
                .header("authorization","Basic c2hlbGxwYzpzaGVsbHBj")
                .method(RequestMethod.POST)
                .form(bodyMap)
                .resultType(R.class)
                .build();
        return request;
    }
}

采用相应的构造者构建相应的请求
在这里插入图片描述

2.5 非bean方式调用

@RestController
@RequestMapping("/client")
@Slf4j
public class HttpClientController {

    @Autowired
    private HttpRequestExecutor httpRequestExecutor;

    public static final String LOGIN_URL = "https://develop.shequtalk.com/auth/oauth/token";

    public static final String GET_URL = "https://develop.shequtalk.com/admin/user/getUserListByDept";
    
    @PostMapping("/testNoBeanWithHutool")
    @Inner(value = false)
    public void testNoBeanWithHutool(){
        HttpRequestClient httpRequestClient = new HutoolRequestClient();
        final HttpRequestExecutor httpRequestExecutor = initHttpRequestExecutor(httpRequestClient);
        HttpRequest request = getLoginRequest();
        final R result = httpRequestExecutor.execute(request);
        log.info("login result : {}",result);
    }

    private HttpRequestExecutor initHttpRequestExecutor(HttpRequestClient httpRequestClient) {

        return new DefaultHttpRequestExecutor(getContext(), httpRequestClient);
    }

    private Context getContext() {
        TimeoutSetting timeoutSetting = new TimeoutSetting();
        Encoder encoder = new DefaultEncoder();
        Decoder decoder = new DefaultDecoder();
        return new DefaultContext(timeoutSetting, decoder, encoder);
    }



    private HttpRequest getLoginRequest() {
        HashMap<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("username","szs");
        bodyMap.put("password","rKu1/348LvKp0rsVC06eCA==");
        bodyMap.put("grant_type","password");

        HttpRequest request = new BodyRequestBuilder<>(LOGIN_URL)
                .header("tenant-id", "6054656364413952")
                .header("authorization","Basic c2hlbGxwYzpzaGVsbHBj")
                .method(RequestMethod.POST)
                .form(bodyMap)
                .resultType(R.class)
                .build();
        return request;
    }
}

三 核心API

/**
 * http请求执行器
 * @author likun
 * @date 2022/7/25 10:14
 */
public interface HttpRequestExecutor {
    /**
     *  执行http请求(异常处理器及前置拦截器均可传入)
     * @param request 核心请求
     * @param requestExceptionHandler 请求发送异常处理器
     * @param responseErrorHandler 相应异常处理器
     * @param requestInterceptor 请求拦截器
     * @param responseInterceptor 相应拦截器
     * @param <T>
     * @return
     */
    <T> T execute(HttpRequest request, RequestExceptionHandler requestExceptionHandler, ResponseErrorHandler responseErrorHandler,
                  RequestInterceptor requestInterceptor, ResponseInterceptor responseInterceptor);

    /**
     * 执行http请求(使用默认的拦截器和异常处理器)
     * @param request
     * @param <T>
     * @return
     */
    default <T> T execute(HttpRequest request){
        return execute(request,null,null,null,null);
    }

    /**
     * 执行http请求 (可以传入请求异常及响应状态码非200的请求处理器)
     * @param request
     * @param requestExceptionHandler
     * @param responseErrorHandler
     * @param <T>
     * @return
     */
    default <T> T execute(HttpRequest request, RequestExceptionHandler requestExceptionHandler, ResponseErrorHandler responseErrorHandler){
        return execute(request, requestExceptionHandler, responseErrorHandler, null, null);
    }

    /**
     * 执行http请求(可以传入请求前置拦截器及响应解码的前置拦截器)
     * @param request
     * @param requestInterceptor
     * @param responseInterceptor
     * @param <T>
     * @return
     */
    default <T> T execute(HttpRequest request, RequestInterceptor requestInterceptor, ResponseInterceptor responseInterceptor) {
        return execute(request, null, null, requestInterceptor, responseInterceptor);
    }


}

四 项目源码

由于改组件的源码较长,这里不在文章中展示,需要的可以私信笔者.

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot 是一个开源的 Java 开发框架,而 MyBatis-Plus 是一个基于 MyBatis 的增强工具库。MyBatis-Plus 提供了很多便捷的功能,使得与数据库的交互更加简单和高效。 要集成 Spring Boot 和 MyBatis-Plus,可以按照以下步骤进行: 1. 添加依赖:在项目的 pom.xml 文件中添加 Spring Boot 和 MyBatis-Plus 的依赖。通常可以在 Maven 中央仓库找到它们的最新版本。 2. 配置数据源:在 application.properties 或 application.yml 文件中配置数据库连接信息,包括数据库 URL、用户名、密码等。 3. 创建实体类:根据需要创建与数据库表相对应的实体类。可以使用注解来标识实体类与数据表的映射关系。 4. 创建 Mapper 接口:创建与实体类对应的 Mapper 接口,用于定义数据库操作的方法。可以使用 MyBatis-Plus 提供的通用 CRUD 方法,也可以根据需求自定义方法。 5. 创建 Service 类:创建 Service 类,用于封装业务逻辑并调用 Mapper 接口中的方法。可以使用注解来标识 Service 类的角色,如 @Service。 6. 配置文件:在 Spring Boot 的配置类中配置 MyBatis-Plus 的相关配置。可以设置数据源、Mapper 扫描路径等。 7. 启动应用程序:根据需要,可以创建一个启动类并添加 @SpringBootApplication 注解。使用 Spring Boot 提供的内嵌容器启动应用程序。 通过以上步骤,就可以完成 Spring Boot 和 MyBatis-Plus 的集成。使用 MyBatis-Plus 提供的丰富功能,可以简化数据库操作,提高开发效率。这个集成方案可以在大多数使用 Spring Boot 的项目中使用,使得与数据库的交互更加方便。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值