- 浏览: 26917 次
文章分类
最新评论
http-invoker
花了一点时间,包装了下httpclient,填了常见的坑。
有兴趣的戳下方链接~~
https://github.com/chenxiaojie/http-invoker
基于apache httpclient的轻量http请求
特性
- 封装了httpclient, 仅暴露常用的配置, 将常见的坑填上
- 接口设计参考jsoup http, 十分便捷的请求让人耳目一新
- 支持所有的请求方式, GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,TRACE
- 可以像rpc请求一样发http请求, 代码更加规范稳定, 易于管理
- 出参入参对json极为友好, 自动解析返回对象to pojo
- 当返回值为HttpResult时, 调用失败也不会抛出异常. GET请求不建议使用HttpResult, 非GET如POST/PUT/DELETE请求都建议使用HttpResult
- 支持返回值取jsonPath, 例如:msg.user.id/msg.user[1].id 参考测试包下com.chenxiaojie.http.invoker.test.http.test.ResultJsonPathTest
- 支持设计重试次数, 建议get请求都有重试机制, 参考测试包下com.chenxiaojie.http.invoker.test.http.test.RetryTest
- 支持上传各种类型的文件, 支持File/InputStream/byte[]/base64上传, 参考测试包下com.chenxiaojie.http.invoker.test.http.test.UploadFileTest
- 支持@PathVariable 如 http://.com/{key}/info -> http://.com/xiaojie.chen/info, 参考测试包下com.chenxiaojie.http.invoker.test.http.test.SimpleTest
- 支持请求拦截器和自定义httpclient, 参考com.chenxiaojie.http.invoker.test.http.test.CustomHttpClientTest
添加依赖
<dependency> <groupId>com.chenxiaojie</groupId> <artifactId>http-invoker</artifactId> <version>1.0.1</version> </dependency>
如果您的项目中有依赖以下包,请指定以下版本或高于以下版本
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.1</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.1</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.9</version> </dependency>
快速入门
http-invoker-demo-web module是专门用于测试, 运行以下代码时, 请先启动这个web项目
使用HttpInvoker, 参考测试包下com.chenxiaojie.http.invoker.test.httpinvoker.HttpInvokerTest
public class HttpInvokerTest { @Test public void testGet() { HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/1") .data("employeeId", "00160041") .data(ImmutableMap.of("employeeName", "陈孝杰1")) .data("ad", "xiaojie.chen", "ad", "xiaojie.chen1") .method(HttpMethod.GET) .execute(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testGet2() { HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/2") .data("employeeId", "00160042") .data(ImmutableMap.of("employeeName", "陈孝杰2")) .data("ad", "xiaojie.chen", "ad", "xiaojie.chen2") .get(); response.log(); Assert.assertTrue(response.isSuccess()); } @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void testGet3() { thrown.expect(HttpRequestException.class); HttpInvoker.Response response = HttpInvoker.builder(HttpClientBuilder.builder().followRedirects(true).build()) .uri(Consts.URL + "/redirect/loop") .get(); response.log(); } @Test public void testPost() { HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/3") .data("employeeId", "00160043") .data(ImmutableMap.of("employeeName", "陈孝杰3")) .data("ad", "xiaojie.chen", "ad", "xiaojie.chen3") .post(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testPost2() { UserLoginModel userLoginModel = new UserLoginModel(); userLoginModel.setLoginId(5); userLoginModel.setEmployeeId("0016004"); userLoginModel.setEmployeeName("陈孝杰"); userLoginModel.setAd("xiaojie.chen"); HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple?employeeName=employeeName陈孝杰") .data("ad", "xiaojie.chen", "ad", "xiaojie.chen3") .json(JSON.toJSONString(userLoginModel)) .post(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testPost3() { InputStream in = Thread.currentThread().getClass().getResourceAsStream("/logo.png"); InputStream in2 = Thread.currentThread().getClass().getResourceAsStream("/logo.png"); HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/file") .data("employeeId", "00160043") .data(ImmutableMap.of("employeeName", "陈孝杰3")) .data("ad", "xiaojie.chen", "ad", "xiaojie.chen3") .data("fileinput", "attachment.png", in) .data("fileinput2", "attachment2.png", in2) .post(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testPut() { UserLoginModel userLoginModel = new UserLoginModel(); userLoginModel.setEmployeeId("0016004"); userLoginModel.setEmployeeName("陈孝杰"); userLoginModel.setAd("xiaojie.chen"); HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/1") .json(JSON.toJSONString(userLoginModel)) .put(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testPatch() { UserLoginModel userLoginModel = new UserLoginModel(); userLoginModel.setEmployeeId("0016004"); userLoginModel.setEmployeeName("陈孝杰"); userLoginModel.setAd("xiaojie.chen"); HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/2") .json(JSON.toJSONString(userLoginModel)) .patch(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testDelete() { HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/1") .data("aa", "陈孝杰") .delete(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testHead() { HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/2") .head(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testOptions() { HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/3") .options(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testTrace() { HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/4") .trace(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testTrace2() { HttpRequestException httpRequestException = null; try { HttpInvoker.Response response = HttpInvoker.builder(HttpClientBuilder.builder().followRedirects(true).build()) .uri(Consts.URL + "/redirect/loop") .trace(); response.log(); } catch (HttpRequestException e) { httpRequestException = e; } Assert.assertNull(httpRequestException); } @Test public void testHeaders() { HttpInvoker.Response response = HttpInvoker.builder(HttpClientBuilder.builder() .header("AAA", "VVV") .header(HttpHeaders.USER_AGENT, "VVVVVVFSDSFSF") .build()) .uri(Consts.URL + "/simple/3") .data("employeeId", "00160041") .data(ImmutableMap.of("employeeName", "陈孝杰1")) .data("ad", "xiaojie.chen", "ad", "xiaojie.chen1") .header("AAA", "BBB") .header("AAA", "BBB2") .headers(ImmutableMap.of("BBB", "CCC")) .headers(ImmutableMap.of(HttpHeaders.USER_AGENT, "ASSSDDSDSDD")) .get(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testCookie() { BasicClientCookie cookie1 = new BasicClientCookie("Auth", "AuthAuth"); cookie1.setPath("/"); cookie1.setDomain("localhost"); BasicClientCookie cookie2 = new BasicClientCookie("Auth2", "Auth2Auth2"); cookie2.setPath("/"); cookie2.setDomain("localhost"); BasicClientCookie cookie3 = new BasicClientCookie("Auth3", "Auth3Auth3"); cookie3.setPath("/"); cookie3.setDomain("localhost"); HttpInvoker.Response response = HttpInvoker.builder(HttpClientBuilder.builder() .header("AAA", "VVV") .header(HttpHeaders.USER_AGENT, "VVVVVVFSDSFSF") .cookie(cookie1) .cookies(Lists.<Cookie>newArrayList(cookie2, cookie3)) .build()) .uri(Consts.URL + "/simple/3") .data("employeeId", "00160041") .data(ImmutableMap.of("employeeName", "陈孝杰1")) .data("ad", "xiaojie.chen", "ad", "xiaojie.chen1") .header("AAA", "BBB") .header("AAA", "BBB2") .headers(ImmutableMap.of("BBB", "CCC")) .headers(ImmutableMap.of(HttpHeaders.USER_AGENT, "ASSSDDSDSDD")) .cookie("Auth", "123") .cookies(ImmutableMap.of("Auth5", "Auth5Auth5", "Auth6", "Auth6Auth6")) .get(); response.log(); Assert.assertTrue(response.isSuccess()); } @Test public void testInterceptor() { HttpInvoker.Response response = HttpInvoker.builder() .uri(Consts.URL + "/simple/3") .data("employeeId", "00160041") .data(ImmutableMap.of("employeeName", "陈孝杰1")) .data("ad", "xiaojie.chen", "ad", "xiaojie.chen1") .header("AAA", "BBB") .header("AAA", "BBB2") .headers(ImmutableMap.of("BBB", "CCC")) .headers(ImmutableMap.of(HttpHeaders.USER_AGENT, "ASSSDDSDSDD")) .cookie("Auth", "123") .cookies(ImmutableMap.of("Auth5", "Auth5Auth5", "Auth6", "Auth6Auth6")) .interceptor(new HttpInvoker.Interceptor() { @Override public boolean intercept(HttpRequestBase httpRequestBase) throws HttpRequestException { System.out.println(httpRequestBase); return true; } }) .interceptor(new BasicAuthInterceptor("AAA", "BBB", "UTF-8")) .get(); response.log(); Assert.assertTrue(response.isSuccess()); } }
通过api的方式请求
java api
public interface SimpleHttpApi { @RequestMapping("/simple/{loginId}") Response<UserLoginModel> queryByLoginId(@PathVariable("loginId") int loginId); @RequestMapping("/simple/{loginId}") HttpResult<Response<UserLoginModel>> queryHttpResultByLoginId(@PathVariable("loginId") int loginId); @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); @RequestMapping(value = "/simple/{loginId}", method = HttpMethod.POST) Response<UserLoginModel> addByLoginId(@PathVariable("loginId") int loginId, @RequestParam(value = "employeeId") String employeeId, @RequestParam(value = "employeeName") String employeeName, @RequestParam(value = "ad") String ad); @RequestMapping(value = "/simple", method = HttpMethod.POST) Response<UserLoginModel> addUser(UserLoginModel userLoginModel); @RequestMapping(value = "/simple", method = HttpMethod.POST) HttpResult<Response<UserLoginModel>> addUser2(@RequestBody UserLoginModel userLoginModel); @RequestMapping(value = "/simple", method = HttpMethod.POST) HttpResult<Response<UserLoginModel>> addUser3(String userLoginModel); @RequestMapping(value = "/simple", method = HttpMethod.POST) HttpResult<Response<UserLoginModel>> addUser4(@RequestBody String userLoginModel); @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); @RequestMapping(value = "/simple/{loginId}", method = HttpMethod.PUT) HttpResult<Response<UserLoginModel>> updateUser(@RequestBody UserLoginModel userLoginModel, @PathVariable("loginId") int loginId, @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); @RequestMapping(value = "/simple/{loginId}", method = HttpMethod.PATCH) HttpResult<Response<UserLoginModel>> patchUser(@RequestBody UserLoginModel userLoginModel, @PathVariable("loginId") int loginId, @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); @RequestMapping(value = "/simple/{loginId}", method = HttpMethod.DELETE) HttpResult<String> deleteUser(@RequestBody UserLoginModel userLoginModel, @PathVariable("loginId") int loginId, @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); }
通过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
<?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>
测试类请参考com.chenxiaojie.http.invoker.test.http.test.SimpleTest
建议
如果请求量比较大, 请尽量自定义httpclient, 否则全局共享一个默认的httpclient
如果请求量比较大, 请将http请求详细日志重置到其他位置或者关闭
日志位置重置
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration status="info"> <Properties> <Property name="log-path">/data/applogs/http-invoker-demo/logs</Property> <Property name="pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} %level [%t] [%c] %msg%xEx%n</Property> </Properties> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true"> <PatternLayout pattern="${pattern}"/> </Console> <RollingFile name="AppAppender" fileName="${log-path}/app.log" filePattern="${log-path}/app.log.%d{yyyy-MM-dd}"> <PatternLayout pattern="${pattern}"/> <Policies> <TimeBasedTriggeringPolicy interval="1"/> </Policies> </RollingFile> <RollingFile name="HttpAppender" fileName="${log-path}/http.log" filePattern="${log-path}/http.log.%d{yyyy-MM-dd}"> <PatternLayout pattern="${pattern}"/> <Policies> <TimeBasedTriggeringPolicy interval="1"/> </Policies> </RollingFile> <Async name="AsyncAppAppender"> <AppenderRef ref="AppAppender" level="info"/> </Async> </Appenders> <loggers> <logger name="com.chenxiaojie.http.invoker.HttpInvoker$Response" additivity="false"> <appender-ref ref="HttpAppender"/> <appender-ref ref="ConsoleAppender"/> </logger> <root level="info"> <appender-ref ref="ConsoleAppender"/> <appender-ref ref="AsyncAppAppender"/> </root> </loggers> </configuration>
关闭日志 spring xml
<?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> <property name="openLog" value="true"></property> </bean> </property> </bean> <!-- 只需配置下方代码即可 --> <bean id="simpleHttpApi" parent="httpParent"> <property name="proxyInterfaces" value="com.chenxiaojie.http.invoker.test.http.api.SimpleHttpApi"/> </bean> </beans>
打包命令
mvn clean install -DskipTests -Dmaven.javadoc.skip=true
维护
有任何问题请随时联系:陈孝杰, qq:3262515, email: 3262515@qq.com
转载于:https://my.oschina.net/chenxiaojie/blog/1542258
相关推荐
focus-http-invoker 此组件主要功能 1 统一http异步调用方式 2 屏蔽底层缓存碎片治理逻辑 3 主动加入appId,便于追溯调用来源 4 简明的API使用 5 将无限的网络请求折叠成有限的请求规模 引入依赖 <groupId>...
《深入理解HTTP Invoker:构建高效HTTP客户端测试与开发实践》 HTTP Invoker,作为一款卓越的HTTP客户端测试工具,其在HTTP开发领域扮演着至关重要的角色。它为开发者提供了便利,使得发送HTTP请求变得简单易行,是...
http-lambda-invoker 一个很小的(<20m)Docker映像,用于通过http调用lambda函数。 这是我第一次尝试golang,因此请多加注意! 是用于开发一些lambda函数的绝佳框架,但要适应基于docker-compose的现有开发工作...
HTTP接口调用框架让 HTTP 接口调用跟调用本地方法一样自然优雅将 HTTP 请求和接口绑定,然后由框架生成接口的代理类,直接调用接口的方法就会自动构建请求参数并发送请求,然后处理请求响应转换为接口方法的返回值...
同时,使用`@HttpInvokerService`注解暴露该服务,指定远程访问的URL。 3. 配置服务消费方:在服务消费方,使用`@HttpInvokerProxyFactoryBean`来创建服务代理,指定服务的URL和接口类型。这样,消费方就可以像调用...
1. **服务端配置**:首先需要在服务端创建一个Spring配置文件,定义远程服务的bean,使用`<bean>`标签并配置`http-invoker-proxy-ref`属性,指定服务接口。 2. **客户端配置**:在客户端,同样需要一个Spring配置...
Spring HTTP Invoker是spring框架中的一个远程调用模型,执行基于HTTP的远程调用,也就是说,可以通过防火墙,并使用java的序列化机制在网络间传递对象。客户端可以很轻松的像调用本地对象一样调用远程服务器上的...
在提供的压缩文件`faas-invoker-main`中,很可能是faas-invoker的主要代码实现或者可执行文件。开发者可以通过分析和修改这个文件,来定制自己的函数执行逻辑,或者优化faas-invoker的行为,以适应特定的业务需求。 ...
服务端还需要配置Servlet容器(如Tomcat)来处理HTTP请求,确保`http-invoker-listener`监听器加载HTTPInvoker的服务。 在客户端,你需要创建一个`HttpInvokerRequestExecutor`,用于执行HTTP调用,然后配置`...
<bean id="myServiceExporter" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> ``` 服务端还需要一个Servlet容器,如Tomcat,部署Spring应用上下文,并配置一个...
let response = invoker.invoke('GET api/hello') return expect(response).to.eventually.have.property('statusCode', 200) }) 上述试验是在一个限定的无服务器功能的测试Serverless.yml如下: functions: ...
HTTP Invoker 是一个Java框架,主要用于在分布式系统中进行远程方法调用(RPC)。它通过HTTP协议提供服务,使得客户端可以像调用本地方法一样调用远程服务。在这个场景下,“http invoker 做post测试”指的是在完成...
【使用httpInvoker提供远程服务】 在分布式系统中,远程服务调用是常见的需求,Spring框架提供了多种远程服务支持,其中包括HttpInvoker。HttpInvoker是Spring框架的一部分,它允许开发者使用HTTP协议进行远程方法...
《HttpInvoker:深入理解HTTP调试工具的奥秘》 在Web开发中,HTTP协议作为互联网应用的基础,扮演着至关重要的角色。为了确保我们的应用程序能够正确地与服务器进行通信,理解和调试HTTP请求至关重要。HttpInvoker...
在等功能服务中使用时,平台会在构建功能并通过添加基本请求/回复http支持时由平台提供调用方启动应用程序。如何使用它功能来源您需要为您的功能配置一个Maven或Gradle项目。 如果您使用Spring Boot,那么我们...
**Spring HttpInvoker的封装** 在Java企业级应用开发中,Spring框架因其强大的功能和灵活性而被广泛应用。HttpInvoker是Spring框架的一部分,它提供了一种基于HTTP协议的远程调用机制,使得不同网络环境中的Java...
`Http Invoker`是Spring框架提供的一种基于HTTP协议的RPC实现,主要用于Java应用程序之间进行服务调用。本文将深入探讨如何使用Http Invoker实现RCP客户端与后台的交互,以及相关知识点。 1. **Http Invoker的基本...
公司内部讲义,比较了SOA,RMI和Spring HttpInvoker。并介绍了Spring HttpInvoker的基本使用方法。
- **deploy/jmx-invoker-adaptor-server.sar**:JMX Invoker适配器服务部署文件。 通过以上总结,可以看出《JBoss Administration and Development, Third Edition (3.2.x Series)》是一本详细介绍JBoss服务器安装...
Hessian、HttpInvoker、XFire和Axis是四种常见的远程调用框架,它们各自有不同的特性和应用场景。 Hessian是一种轻量级的二进制RPC协议,它通过HTTP进行传输,减少了网络开销,提高了服务调用效率。Hessian提供了...