公司内部一般都是用自研的rpc pigeon
但是涉及到第三方合作都会使用http请求,如果你尝试使用httpclient你又会被众多的版本和不同的api所困扰,经常忘记设置线程数,忘记设置超时时间等。
就算你搞定了httpclient,你会发现与第三方定义的请求方式和描述难于维护,交于第二个维护的时候代码不容易阅读,于是基于javaAPI来请求http请求的想法萌生,就有了如下的微框架。
本框架有如下优势:
- 基于httpclient, 仅暴露常用的配置, 填掉了常见的坑
- 接口设计参考jsoup, 简易的语法让人耳目一新
- 支持所有的请求方法:GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,TRACE
- 出参入参对json极为友好, 自动解析返回对象to pojo
- 可以像rpc一样基于java api发送http请求, 代码更加规范稳定, 易于管理
- 当返回值为HttpResult时, 调用失败也不会抛出异常.
- 支持返回值取json path, 例如:msg.user.id/msg.user[1].id 参考测试包下 ResultJsonPathTest
- 支持设计重试次数, 建议get请求都有重试机制, 参考测试包下 RetryTest
- 支持上传各种类型的文件, 支持File/InputStream/byte[]/base64上传, 参考测试包下 UploadFileTest
- 支持@PathVariable 如 http://.com/{key}/info -> http://.com/xiaojie.chen/info, 参考测试包下 SimpleTest
- 支持自定义httpclient, 参考 CustomHttpClientTest
- 自定义请求拦截器可以作于自定义授权
- 日志清晰,排查case十分方便
- 支持自定义植入监控,如大众点评的cat
- 开发者正处壮年,有问题立即反馈~~哈哈哈
具体的源码和使用方式请访问:
https://github.com/chenxiaojie/http-invoker
使用入门:
最简单的实例,先定义个httpapi
public interface SimpleHttpApi {
//get
@RequestMapping(value = "/simple/{loginId}", method = HttpMethod.GET)
Response<UserLoginModel> getByLoginId(@PathVariable("loginId") int loginId,
@RequestParam(value = "employeeId") String employeeId,
@RequestParam(value = "employeeName") String employeeName,
@RequestParam(value = "ad") String ad);
//post
@RequestMapping(value = "/{path}", method = HttpMethod.POST)
HttpResult<Response<UserLoginModel>> addUser5(@RequestBody UserLoginModel userLoginModel,
@PathVariable("path") String path,
@RequestParam(value = "employeeId") String employeeId,
@RequestParam(value = "employeeId") String employeeId2,
@RequestParam(value = "employeeId") String employeeId3,
@RequestParam(value = "employeeName") String employeeName,
@RequestParam(value = "ad") String ad);
//upload
@RequestMapping(value = "/{path}", method = HttpMethod.POST)
HttpResult<Response<String>> upload(@RequestFile("a1.png") InputStream in,
@RequestFile("a2.png") File file,
@RequestFile("a3.png") byte[] fileBytes,
@RequestFile("a4.png") String base64,
@PathVariable("path") String path,
@RequestParam(value = "employeeId") String employeeId,
@RequestParam(value = "employeeId") String employeeId2,
@RequestParam(value = "employeeId") String employeeId3,
@RequestParam(value = "employeeName") String employeeName,
@RequestParam(value = "ad") String ad);
//retry
@RequestMapping(value = "/simple/{loginId}", method = HttpMethod.GET, retryTimes = 1)
HttpResult<Response<UserLoginModel>> getByLoginId(@PathVariable("loginId") String loginId,
@RequestParam(value = "employeeId") String employeeId,
@RequestParam(value = "employeeName") String employeeName,
@RequestParam(value = "ad") String ad);
//jsonPath
@RequestMapping(value = "/simple/list", method = HttpMethod.GET, retryTimes = 1, resultJsonPath = "data[1].employeeName")
String queryUsers();
}
通过java方式调用
HttpInvocationHandler httpInvocationHandler = new HttpInvocationHandler();
httpInvocationHandler.setRequestUrlPrefix(Consts.URL);
SimpleHttpApi simpleHttpApi = (SimpleHttpApi) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class[]{SimpleHttpApi.class},
httpInvocationHandler);
UserLoginModel userLoginModel = new UserLoginModel();
userLoginModel.setLoginId(1);
userLoginModel.setEmployeeId("0016004");
userLoginModel.setEmployeeName("陈孝杰");
userLoginModel.setAd("xiaojie.chen");
Response<UserLoginModel> response = simpleHttpApi.addUser(userLoginModel);
System.out.println(response.getData());
通过spring方式调用
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="httpParent" class="com.chenxiaojie.http.invoker.spring.HttpProxyFactoryBean" abstract="true" init-method="init">
<property name="invocationHandler">
<bean class="com.chenxiaojie.http.invoker.proxy.HttpInvocationHandler">
<property name="requestUrlPrefix" value="http://localhost:8081/httpinvoker"></property>
</bean>
</property>
</bean>
<!-- 只需配置下方代码即可 -->
<bean id="simpleHttpApi" parent="httpParent">
<property name="proxyInterfaces" value="com.chenxiaojie.http.invoker.test.http.api.SimpleHttpApi"/>
</bean>
</beans>