http-invoker

花了一点时间,包装了下httpclient,填了常见的坑。

有兴趣的戳下方链接~~

https://github.com/chenxiaojie/http-invoker

基于apache httpclient的轻量http请求

特性

  1. 封装了httpclient, 仅暴露常用的配置, 将常见的坑填上
  2. 接口设计参考jsoup http, 十分便捷的请求让人耳目一新
  3. 支持所有的请求方式, GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,TRACE
  4. 可以像rpc请求一样发http请求, 代码更加规范稳定, 易于管理
  5. 出参入参对json极为友好, 自动解析返回对象to pojo
  6. 当返回值为HttpResult时, 调用失败也不会抛出异常. GET请求不建议使用HttpResult, 非GET如POST/PUT/DELETE请求都建议使用HttpResult
  7. 支持返回值取jsonPath, 例如:msg.user.id/msg.user[1].id 参考测试包下com.chenxiaojie.http.invoker.test.http.test.ResultJsonPathTest
  8. 支持设计重试次数, 建议get请求都有重试机制, 参考测试包下com.chenxiaojie.http.invoker.test.http.test.RetryTest
  9. 支持上传各种类型的文件, 支持File/InputStream/byte[]/base64上传, 参考测试包下com.chenxiaojie.http.invoker.test.http.test.UploadFileTest
  10. 支持@PathVariable 如 http://.com/{key}/info -> http://.com/xiaojie.chen/info, 参考测试包下com.chenxiaojie.http.invoker.test.http.test.SimpleTest
  11. 支持请求拦截器和自定义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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值