# slow-creator-http
**Repository Path**: kelr/slow-creator-http
## Basic Information
- **Project Name**: slow-creator-http
- **Description**: slow-creator-http用于http请求的调用与解析,通过接口与注解即可实现http请求的调用与解析,避免项目出现多处重复请求与解析代码。
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 2
- **Created**: 2023-01-08
- **Last Updated**: 2023-06-13
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Slow-Creator-Http 一款Http请求的调用工具
Slow-Creator-Http是项目Slow-Creator的一个模块,用于http请求的调用与解析,通过接口与注解即可实现http请求的调用与解析,避免项目出现多处重复请求与解析代码。
# 项目介绍
项目需要对接第三方的时候,即使封装了Http的请求工具类但是也避免不了需要各种自定义的情况,并且对于返回值的解析,例如json格式,需要先反序列化,然后判断返回的状态是否成功。
本项目的思路来源于[转转支付网关之注解式HTTP客户端 - 掘金](https://juejin.cn/post/7182460718506049594) ,但是本项目未接入spring相关依赖,可以在非spring环境下使用
## 工作流程

通过构建请求参数,调用对应的请求接口(接口类需要~~标注`com.gitee.slowcreator.http.annotation.HttpInterface`注解~~,
由于增加了实现类,避免歧义,该注解已废弃,使用`com.gitee.slowcreator.http.annotation.HttpEnhance`标注接口或实现类),
请求接口会进行动态代理,进入执行流程后会先进行前置处理,此时可以进行相应的设置,实际请求通过spi的方式查找用户项目中引入的http工具。
如果请求失败或者是在后置处理的过程中发现请求失败了会进行再次调用(如果配置了重试,可通过`com.gitee.slowcreator.http.annotation.Retry` 注解配置)。如果不重试或者到达重试上限会通过是否抛出异常配置检测当前调用结果是通过抛出异常接受还是返回调用失败结果。
## 调用
> 第一次获取代理类之前可通过 `ScHttpConfig.setInterfacePackage("com.xxx");`设置接口的扫描的路径,如果不设置会进行全包扫描,耗时会很久。
> 如果项目中存在hutool和okhttp两种依赖,可以通过`ScHttpConfig.setFixedHttp(HttpExecutorConstant.XXX);`设置指定执行器,可参考测试类。
> 如果重写了`com.gitee.slowcreator.http.executor.HttpExecutor`(SPI方式),并且重写了executorType(),
> 也可以使用`ScHttpConfig.setFixedHttp(XXX);`传入使用用户自定义的执行器,
> 请在第一次调用前设置,否则设置会失败,会使用第一次获取的http执行器。
> okhttp相关配置如果需要定制化或者项目以已存在OkHttpClient,
> 可以通过`com.gitee.slowcreator.http.config.ScHttpConfig#setAndGetOkHttpClient(OkHttpClient)`传入。
> 如果传入了OkHttpClient,请设置OkHttpClient#addInterceptor(new OkhttpTimeoutInterceptor()) 否则超时时间定制化的功能设置会失效,
> 默认调用不需要配置这个参数
### 使用
以下以测试类为例
设置扫描路径并获取代理类
```java
ITestHttpRequest proxy = null;
@Before
public void before() {
// 设置扫描包路径
ScHttpConfig.setInterfacePackage("com.gitee");
proxy = HttpClientContext.getHttpClient(ITestHttpRequest.class);
}
```
接口类设置
```java
@HttpInterface(desc = "测试接口")
public interface ITestHttpRequest {
/**
* 测试post请求
*
* @param header
* @param params
* @param returnHeader
* @param body
* @return
*/
@HttpClient(
desc = "测试POST",
url = "http://127.0.0.1:8080/annotationHttp/testPost",
failThrow = true,
throwException = HttpRequestException.class,
timeout = 10000,
requestType = RequestType.POST
)
ScReturn testPost(@HttpHeader Map header,
@HttpParams Map params,
@HttpReturnHeader Set returnHeader,
ScBody body);
/**
* 测试ScUnionParams直接请求
*
* @param unionParams
* @return
*/
@HttpClient(
desc = "测试UNION",
url = "http://127.0.0.1:8080/annotationHttp/testPost",
failThrow = true,
throwException = HttpRequestException.class,
timeout = 10000,
requestType = RequestType.POST
)
ScReturn testUnion(ScUnionParams unionParams);
/**
* 测试url覆盖
*
* @param url
* @return
*/
@HttpClient(desc = "测试GET", url = "666")
ScReturn testUrlChange(@HttpUrl String url);
}
```
`测试POST 说明`
requestType 默认为RequestType.GET,如果是非GET调用需要指定,此处演示了两种传参方式,可通过注解标注传参也可通过指定类进行传参,可以避免写注解。具体类型可见`com.gitee.slowcreator.http.params.ScUnionParams`
如果参数为指定类型传入,则可以省略对应的注解,使用非自带类型(实现了`com.gitee.slowcreator.http.params.ScBase`的类)的话,类型需要符合规范并且添加注解
注解详细说明可见`com.gitee.slowcreator.http.annotation.HttpClient`
`测试UNION 说明`
如果需要的参数很多,可以使用`com.gitee.slowcreator.http.params.ScUnionParams`传入,通过注解或者是自带类型传入最终也是封装成`com.gitee.slowcreator.http.params.ScUnionParams`,使用`ScUnionParams`传入会自动忽略其他参数,包括注解和自带类型,`ScUnionParams`传入不需要注解。
`测试url覆盖 说明`
如果是进行一次简单的调用可以参考`测试GET`进行,只需要传入一个url即可,desc非必须,只是加了个说明。
此次演示了url替换,由于有些时候调用存在生产、开发、测试多种环境,在注解是写死不现实,可以通过`@HttpUrl`进行替换。
> 不同传参方式存在不同的优先级 ScUnionParams > 自带类型 > 注解
### retry
如果需要支持retry可以通过`@HttpClient`的`retry`进行配置,相应参数可查阅`com.gitee.slowcreator.http.annotation.Retry`,默认不开启retry。
### 后置处理
目前后置处理增加了一个json解析,通过传入状态标准和状态值判断本次调用是否成功,json解析类型也是通过一个Type传入,这些新增的参数通过ThreadLocal进行传入。
### 自定义代理接口实现类
如果需要自定义接口的实现类去处理逻辑 需要在请求方法上加上`@HttpResult ScReturn scReturn` 则会把http请求的结果传入,实现类可以通过这个类获取http请求的结果信息
如果实现了接口 则返回值可以根据需要返回自定义类型 非强制返回 `ScReturn`(未实现http接口的话返回值必须是`ScReturn`类型)
具体可以参考`com.gitee.slowcreator.module.http.request.intface.ITestHttpEnhance`以及对应的实现类,使用方法参考`com.gitee.slowcreator.module.http.request#testImpl`
### 下载
新版下载功能单独拿了出来,通过实现`com.gitee.slowcreator.http.file.download.IFileDownload`,实现文件下载为byte array形式和文件形式。
`HttpClient` 新增`Download`注解参数(旧版本`HttpClient`的下载处理参数: ~~`download`、`downloadLocal`、`downloadLocalFilename`~~ 已废弃使用),
下载请求需要设置`Download`注解的`download`参数为`true`,如果想获取下载数据自行处理,可以设置`useByte`为`true`(默认值),文件数据会存在`ScReturn`下`downloadResult`的`data`里面,
如果需要边下载边写入本地,需要设置`useByte`为`false`(`data`里面没有数据),`fileDownloadHandle`为下载的处理类,当前项目已实现 OkHttp 和 Hutool 请求工具的 byte array 形式和文件写入本地形式,
如果使用的是minio、FastDFS可以自行扩展。然后传入对应的实现类即可。
> 注意:`fileDownloadHandle`上设置的参数默认为单例,默认调用`com.gitee.slowcreator.http.file.download.FileDownloadFactory#getHandle(Class extends IFileDownload> fileDownloadClass)`获取,
> 所以在实现类中,请勿使用有状态的参数,否则可能会出现线程安全问题,如果不想使用单例可以将调用这个方法的地方
> 改成调用调用`com.gitee.slowcreator.http.file.download.FileDownloadFactory#getHandle(Class extends IFileDownload> fileDownloadClass, boolean newInstance)`第二个参数传入true,既每次调用都会新创建一个实例。
默认两种下载通过`com.gitee.slowcreator.http.file.download.template.AbstractByteFileDownload`和`com.gitee.slowcreator.http.file.download.template.AbstractLocalFileDownload`
实现了byte array形式和文件写入本地形式的模板,两种http请求库,继承对应的类,对抽象方法进行单独的处理。
> 注意:如果使用的是 `Hutool`,下载本地的话`HttpClient`需要设置`isAsync = true`,否则做不到边下载边写入。
> `OkHttp`可以不设置这一步,因为 `OkHttp` 设置了 `isAsync = true` 会变成一个异步请求,而 `Hutool` 设置了并不会把当前请求变成异步。
> 具体使用可以参考`com.gitee.slowcreator.module.http.request.intface.ITestHttpRequest`的`testNewOkHttpDownloadByte`、`testNewOkHttpDownloadLocal`、`testNewHutoolDownloadByte`、`testNewHutoolDownloadLocal`
> (默认这四个下载方法的地址如果失效,可自行传入一个文件下载地址测试)
### 添加方式
由于本项目未上传中央仓库,可以本地执行`mvn install`后引入,或者执行 `mvn clean package -Dmaven.test.skip=true` 将jar包上传至私服中再引入
pom文件引入
```xml
com.gitee.slowcreator
slow-creator-http
2.1.0
```
## 说明
本项目借鉴了:
- 转转支付网关之注解式HTTP客户端
- Spring-Retry
- Mybatis
- Hutool
测试相关可见test包相关代码,测试Controller代码在doc包下TestAnnotationHttp.java,本项目未引入web相关依赖,需要在其他引入springboot相关项目中使用。
### todo
- [ ] retry的延迟实现
- [x] okhttp等其他工具接入