Score
0
Watch 1 Star 3 Fork 2

蒋固金 / JHttpJavaApache-2.0

Create your Gitee Account
Explore and code with more than 5 million developers,Free private repositories !:)
Sign up
JHttp是用java编写的用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,基于原生的HttpUrlConnection实现,支持:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE请求,可以适应绝大部分业务场景,并提供了丰富的请求操作的API,使开发者更加方便快捷的完成HTTP的请求工作。 spread retract

Clone or download
Cancel
Notice: Creating folder will generate an empty file .keep, because not support in Git
Loading...
README.md

第一部分 简介

JHttp是用java 编写的用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,基于原生的HttpUrlConnection实现,支持:GETPOSTPUTDELETEPATCHHEADOPTIONSTRACE请求,可以适应绝大部分业务场景,并提供了丰富的请求操作的API,使开发者更加方便快捷的完成HTTP的请求工作。

第二部分 开始使用

使用JHttp可以直接下载源代码编译或者下载已经编译的jar文件,如果您是使用maven来构建项目,也可以直接在pom.xml中添加JHttp的坐标:

Maven central

<!-- http://mvnrepository.com/artifact/com.jianggujin/JHttp -->
<dependency>
    <groupId>com.jianggujin</groupId>
    <artifactId>JHttp</artifactId>
    <version>最新版本</version>
</dependency>

最新的版本可以从Maven仓库或者码云获取。

2.1 一个例子

请求文本是最基本的用法,比如下载一个网页的源码或者普通的接口调用,以访问百度为例,我们可以这样写:

JResponse response = new JTextResponse();
JRequest request = JRequest.create("https://www.baidu.com").response(response);
JRequestExecuter executer = new JDefaultRequestExecuter();
executer.execute(request);
System.out.println(response.getData());

对于一次网络请求需要有请求执行器、请求对象与响应对象,这三部分构成了完整的请求流程。一般情况下每个请求都应该有响应,我们可以通过JRequest.response(JResponse response)设置响应的处理对象,上面的例子中使用的是JTextResponse,该类是文本响应的处理对象。除此之外,JHttp还提供了字节数组、文件等响应的处理。

默认情况下,JRequest使用GET请求方式,我们可以通过JRequest.method(JMethod method)设置请求方法,JRequest中还提供了一些常用的操作方法,比如超时时间、字符编码等。

如果我们不需要创建独立的JRequestExecuter,可以直接使用JRequest对象的execute()方法。

2.2 设置请求参数

通常情况,我们在网络请求的时候会传递一些请求参数,我们可以使用JRequest提供的data方法设置请求参数,该方法有几个重载方法,我们可以按照实际情况选择。

String url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx/getWeather";
JRequest request = JRequest.create(url).method(JMethod.POST).response(new JTextResponse())
        .data("theCityCode", "2009").data("theUserID", "");
JRequestExecuter executer = new JDefaultRequestExecuter();
executer.execute(request);
System.out.println(request.response().getData());

2.3 设置请求体

有些时候,我们可能不仅仅是传递普通参数,我们可能希望直接发送一段文本,比如Restful接口提交JSON格式数据,使用JHttp也可以很方便的处理这种需求,在JRequest中有requestBody(Object body)方法可以设置要提交的请求体,默认的请求体的处理支持:CharSequenceMapbyte[]char[]

我们可以这样使用:

String url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx/getWeather";
JRequest request = JRequest.create(url).method(JMethod.POST).response(new JTextResponse())
        .requestBody("theCityCode=2009&theUserID=");
JRequestExecuter executer = new JDefaultRequestExecuter();
executer.execute(request);
System.out.println(request.response().getData());

如果默认的实现不满足我们的需求,我们可以自定义自己的解析器,编写解析器我们只需要实现com.jianggujin.http.request.JRequestBodyResolver接口并通过JRequest.requestBodyResolver(JRequestBodyResolver requestBodyResolver)设置请求指定解析器,这种方式级别最高,如果不设置请求的解析器,请求执行器会尝试查找已经注册的解析器。注册的请求体解析器与请求执行器生命周相同,所以我们可以通过请求执行器获得相关注册器实现注册。

executer.getRequestBodyResolverRegistrar().register(requestBodyResolver, true);

该方法接收两个参数,第一个参数为请求体解析器对象,第二个参数为是否重写,即当出现同名解析器的时候是否替换,如果不替换则会抛出异常。JHttp提供了一个名为default的默认的请求体解析器,支持CharSequenceMapByteBufferbyte[]char[]的数据类型转换。

2.4 请求响应处理

JRequest中提供了response(JResponse response)方法用于设置响应处理对象,JHttp提供了如下几种响应实现:

  • JByteBufferResponse - 将响应解析为ByteBuffer

  • JByteResponse - 字节数组响应

  • JFileResponse - 文件响应

  • JJsonResponse - JSON响应

  • JNoBodyResponse - 无响应体的响应

  • JTextResponse - 文本响应

  • JXMLDomResponse - XML响应,DOM方式解析

  • JXmlResponse - XML响应

  • JXMLSaxResponse - XML响应,SAX方式解析

需要注意的是JJsonResponseJXmlResponse,这两个响应用于将响应的数据转换为指定的Java Bean,但是并未提供相关实现,如果我们需要这部分功能,可以实现相对应的JJsonResolverJXmlResolver接口,并调用对应的setResolver方法设置解析实现,这样可以完成对默认响应的扩展。

如果默认提供的响应处理不满足实际需求,我们也可以实现JResponse接口,或者直接继承JAbstractResponse,按照实际需求处理响应。

2.5 设置代理

如果程序运行环境存在网络限制,需要代理访问,我们只需要为请求设置代理对象,方法为proxy(Proxy proxy)

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));
JRequest.create(url).proxy(proxy );

2.6 SSL

在处理https请求的时候,我们可能需要做SSL的设置,JHttp提供了JSSLContextFactory接口用于初始化SSLContextHostnameVerifier,为了使用方便,JHttp提供了一个JDefaultSSLContextFactory,我们只需要传递协议算法即可,该类默认忽略证书的验证,并且信任所有主机,为了安全考虑,还是建议实现规范的处理。

2.7 Cookie

如果我们需要做请求的会话保持,使用JHttp可以很方便的添加Cookie信息,在JRequest中,我们提供了几个cookie的重载方法,方便我们在请求之前添加cookie信息。 因为JHttp是基于HttpUrlConnection的,所以全局的CookieManager对于JHttp同样有效。

CookieManager manager = new CookieManager();
CookieHandler.setDefault(manager);

new JDefaultRequestExecuter().execute(JRequest.create("https://www.baidu.com"));

for (HttpCookie cookie : manager.getCookieStore().getCookies()) {
   System.out.printf("%s=%s,domain=%s,path=%s\n",
      cookie.getName(),
      cookie.getValue(),
      cookie.getDomain(),
      cookie.getPath());
}

2.8 请求回调

如果我们需要对请求添加日志等处理,我们可以实现com.jianggujin.http.request.JRequestExecuterListener接口,该接口会在请求执行前与请求之行结束进行相关方法的回调,方便我们做日志记录等处理,在JHttp中也提供了一个默认的日志实现类com.jianggujin.http.request.impl.JRequestExecuterLog,当然了,这个类仅仅是做了最简单的打印输出。

executer.setRequestExecuterListener(new JRequestExecuterLog());

这种方式会对请求执行器的所有请求生效,如果想只针对某个请求生效,可以使用如下形式:

executer.execute(request, new JRequestExecuterLog());

第三部分 扩展

JHttp除了上面的基本使用之外,还支持动态代理方式,通过定义API接口配合提供的注解,可以更加方便快捷的完成请求处理。使用接口形式,我们首先需要定义请求的接口,举个例子:

@JBaseUrl("http://ws.webxml.com.cn")
public interface Weather {
    @JApiRequest(value = "/WebServices/WeatherWS.asmx/getWeather", method = JMethod.POST)
    String weather(@JRequestParam("theCityCode") String theCityCode, @JRequestParam("theUserID") String theUserID);
}

定义完接口,我们需要使用JApiFactory获得接口的代理实现:

JApiFactory apiFactory = new JApiFactory();
apiFactory.getApi(Weather.class).weather("2009", "");

接口方法中如果含有JResponseProxyJSSLContextFactoryJRequestBodyResolverJMethodJKeyVal类型的参数,会直接将其设置在请求对象中。

3.1 常用注解

3.1.1 JApiRequest

设置API请求信息,用于设置请求路径方法等信息,可以用在方法上面。与JBaseUrl搭配使用,会将域名与路径进行拼接。

3.1.2 JApiRequestBodyResolver

请求体解析器,用于指定当前请求使用的请求体解析器。

3.1.3 JApiResponseResolver

响应解析器,用于指定当前请求使用的响应体解析器。

3.1.4 JBaseUrl

请求地址,通常为域名,例如:http://www.baidu.com

3.1.5 JCookie

Cookie

  • 当注解为类注解,则required()无效, 会根据itemDelimiter()kvDelimiter()的配置对value()进行拆分

  • 当注解为方法注解,则required()无效, 会根据itemDelimiter()kvDelimiter()的配置对value()进行拆分

  • 当注解为方法参数注解,则itemDelimiter()kvDelimiter()的配置无效, 如果方法参数类型为String,则value()必须配置,对应值为Cookie名称,方法参数为Cookie值; 如果方法参数类型为Map,则所有参数无效,方法参数即为Cookie数据

  • 注解解析顺序为类注解 -> 方法注解 -> 方法参数注解。同名参数会覆盖

3.1.6 JHeader

请求头

  • 当注解为类注解,则required()无效, 会根据itemDelimiter()kvDelimiter()的配置对value()进行拆分

  • 当注解为方法注解,则required()无效, 会根据itemDelimiter()kvDelimiter()的配置对value()进行拆分

  • 当注解为方法参数注解,则itemDelimiter()kvDelimiter()的配置无效, 如果方法参数类型为String,则value()必须配置,对应值为请求头名称,方法参数为请求头值; 如果方法参数类型为Map,则所有参数无效,方法参数即为请求头

  • 注解解析顺序为类注解 -> 方法注解 -> 方法参数注解。同名参数会覆盖

3.1.7 JPathParam

路径参数,路径参数形如{name}

  • 如果方法参数类型为String,则value()必须配置,对应值为路径参数名称,方法参数为路径参数值; 如果方法参数类型为Map,则所有参数无效,方法参数即为路径参数数据

3.1.8 JRequestParam

请求参数,可以用在方法方法参数上面。当注解用在方法参数上面的时候

  • 如果参数为String,首先会判断value是否为空串,是则注解参数用法相同,不是则value为请求参数名称,参数值为对应请求参数的值
  • 如果参数为Collection数组,则仅有kvDelimiter参数有效
  • 如果参数为Map则所有参数无效

3.1.9 JRequestBody

设置请求体,可以用在方法参数上。

3.2 默认响应

为了方便对响应数据的处理,JHttp提供了一些默认的操作,在没有主动设置响应对象或响应解析器的情况下,则会根据方法返回值创建响应对象。支持的返回类型以及对应的相应处理类如下:

返回类型 响应类
java.lang.String JTextResponse
byte[] JByteResponse
java.nio.ByteBuffer JByteBufferResponse
java.io.File JFileResponse
org.w3c.dom.Document JXMLDomResponse

需要注意的是响应对象的getData()方法的返回值必须与接口方法返回值类型匹配,如果不匹配且返回类型为JResponse,则会返回响应对象,否则会永远返回null

与请求解析器类似,我们也可以更改默认的响应解析器:

apiFactory.getResponseResolverRegistrar().register(responseResolver, true);

3.3 插件

接口动态代理的形式简化了我们的开发工作,有些特殊的场景可能需要动态修改参数或拦截请求,这种情况就需要借助插件来完成。下面我们就通过一个小例子演示插件的使用。

@JIntercepts({ @JSignature(type = Weather.class) })
public class Interceptor extends JAbstractInterceptor {
    @Override
    public Object intercept(JInvocation invocation) throws Throwable {
        System.out.println("插件开始工作");
        return invocation.proceed();
    }
}

想要插件生效,我们需要在获得代理对象之前进行设置:

apiFactory.addInterceptor(new Interceptor());

上述插件中演示了插件最基本的用法,编写插件首先需要继承com.jianggujin.http.support.plugin.JAbstractInterceptor,或者直接实现com.jianggujin.http.support.plugin.JInterceptor接口,在实现的方法中最主要关心intercept方法,最后一定不要忘记调用invocation.proceed(),否则后续流程会终止。

一个插件可以拦截多个接口代理,这需要依赖@JIntercepts@JSignature注解,@JSignature注解指定了需要拦截的方法的签名,默认情况在该注解中的method属性为空,表示拦截对应接口代理下的所有方法,如果不需要这样做,则需要指定方法名与对应的参数说明以便于定位到指定的方法。

第四部分 SpringBoot集成

JHttp同样提供了对SpringBoot的支持,内置自动装配实现,开发者仅需要关心接口的编写,在需要使用的地方可以直接注入,大大的简化的开发流程。

在不进行任何配置的情况下,想要自动装配扫描并代理我们的接口,需要在接口上添加@JApiInterface注解,;另一种形式就是我们将接口放在一个专用的包下面,通过在SpringBoot的配置类上面添加@JApiScan注解可以更加个性化的对自动装配的接口进行配置。

package com.jianggujin.http.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.jianggujin.http.test.api.Weather;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootApiTest {

    @Autowired
    private Weather weather;

    @Test
    public void test() throws Exception {
        System.err.println(weather.weather("2009", ""));
    }
}

Comments ( 3 )

Sign in for post a comment

Java
1
https://gitee.com/jianggujin/JHttp.git
git@gitee.com:jianggujin/JHttp.git
jianggujin
JHttp
JHttp
master

Search

231008 48f1a665 1899542 231017 9a6720c6 1899542