JHttp
是用java
编写的用来提供高效的、最新的、功能丰富的支持HTTP
协议的客户端编程工具包,基于原生的HttpUrlConnection
实现,支持:GET
、POST
、PUT
、DELETE
、PATCH
、HEAD
、OPTIONS
、TRACE
请求,可以适应绝大部分业务场景,并提供了丰富的请求操作的API,使开发者更加方便快捷的完成HTTP
的请求工作。
使用JHttp
可以直接下载源代码编译或者下载已经编译的jar
文件,如果您是使用maven
来构建项目,也可以直接在pom.xml
中添加JHttp
的坐标:
<!-- http://mvnrepository.com/artifact/com.jianggujin/JHttp -->
<dependency>
<groupId>com.jianggujin</groupId>
<artifactId>JHttp</artifactId>
<version>最新版本</version>
</dependency>
请求文本是最基本的用法,比如下载一个网页的源码或者普通的接口调用,以访问百度为例,我们可以这样写:
JResponse response = new JTextResponse();
JRequest.create("http://www.baidu.com").response(response).execute();
System.out.println(response.getData());
JRequest
是所有请求的入口,我们可以直接使用该类提供的静态方法create
创建一个请求对象,也可以使用该类的构造方法实例化请求对象。在JRequest
中,提供了链式调用的方法,上面的例子中的请求,我们可以用一行代码完成。
JRequest.create("http://www.baidu.com").response(response).execute()
.response().getData();
每个请求都应该有响应,我们可以通过JRequest.response(JResponse response)
设置响应的处理对象,上面的例子中使用的是JTextResponse
,该类是文本响应的处理对象。除此之外,JHttp
还提供了字节数组、文件等响应的处理。
默认情况下,JRequest
使用GET
请求方式,我们可以通过JRequest.method(JMethod method)
设置请求方法,JRequest
中还提供了一些常用的操作方法,比如超时时间、字符编码等。
通常情况,我们在网络请求的时候会传递一些请求参数,我们可以使用JRequest
提供的data
方法设置请求参数,该方法有几个重载方法,我们可以按照实际情况选择。
String url = "https://www.sojson.com/open/api/weather/json.shtml";
Object obj = JRequest.create(url).data("city", "南京")
.response(new JTextResponse()).execute()
.response().getData();
System.out.println(obj);
JRequest
不仅支持普通的文本参数,还支持上传文件。
File uploadFile = new File("test.txt");
Object obj = JRequest.create("http://127.0.0.1/test/upload")
.method(JMethod.POST)
.data("uploadFile", uploadFile.getName(),
new FileInputStream(uploadFile)).response(new JTextResponse())
.execute().response().getData();
System.out.println(obj);
这样就可以上传文件,是不是很简单,不过需要注意的是,上传文件的时候需要使用POST
、PUT
这样允许请求体的请求方法。
有些时候,我们可能不仅仅是传递普通参数或者上传文件,我们可能希望直接发送一段文本,比如Restful
接口提交JSON
格式数据,使用JHttp
也可以很方便的处理这种需求,在JRequest
中有requestBody(Object body)
方法可以设置要提交的请求体,默认的请求体的处理支持:CharSequence
、Map
、byte[]
和char[]
。
我们可以这样使用:
Object obj = JRequest.create("http://127.0.0.1/test/user")
.method(JMethod.POST)
.header("Content-Type", "application/json")
.requestBody("{\"name\":\"jianggujin\"}")
.response(new JTextResponse()).execute()
.response().getData();
System.out.println(obj);
如果默认的实现不满足我们的需求,我们可以自定义自己的解析器,编写解析器我们只需要实现com.jianggujin.http.core.JRequestBodyResolver
接口,该接口需要实现两个方法,write
方法用于向输出流中写入数据,support
方法用于判断解析器是否支持该类型数据解析(通过JRequest
设置的解析器该方法无效,不会做判断)。
我们可以通过JRequest.requestBodyResolver(JRequestBodyResolver requestBodyResolver)
设置请求指定解析器,这种方式级别最高,如果不设置请求的解析器,则会查找全局解析器。全局解析器支持代码注册和ServiceLoader
形式加载,代码注册需要调用JRequestBodyResolverFactory.register(JRequestBodyResolver resolver)
方法,ServiceLoader
形式只需要在META-INF/services/com.jianggujin.http.core.JRequestBodyResolver
文件中添加需要的实现即可。
在JRequest
中提供了response(JResponse response)
方法用于设置响应处理对象,JHttp
提供了如下几种响应实现:
JByteBufferResponse - 将响应解析为ByteBuffer
JByteResponse - 字节数组响应
JFileResponse - 文件响应
JJsonResponse - JSON响应
JNoBodyResponse - 无响应体的响应
JTextResponse - 文本响应
JXMLDomResponse - XML响应,DOM方式解析
JXmlResponse - XML响应
JXMLSaxResponse - XML响应,SAX方式解析
需要注意的是JJsonResponse
与JXmlResponse
,这两个响应用于将响应的数据转换为指定的Java Bean
,但是并未提供相关实现,如果我们需要这部分功能,可以实现相对应的JJsonResolver
和JXmlResolver
接口,并调用对应的setResolver
方法设置解析实现,这样可以完成对默认响应的扩展。
如果默认提供的响应处理不满足实际需求,我们也可以实现
JResponse
接口,或者直接继承JAbstractResponse
,按照实际需求处理响应。
如果程序运行环境存在网络限制,需要代理访问,我们只需要为请求设置代理对象,方法为proxy(Proxy proxy)
,
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));
JRequest.create(url).proxy(proxy );
在处理https
请求的时候,我们可能需要做SSL
的设置,JHttp
提供了JSSLContextFactory
接口用于初始化SSLContext
和HostnameVerifier
,为了使用方便,JHttp
提供了一个JDefaultSSLContextFactory
,我们只需要传递协议算法即可,该类默认忽略证书的验证,并且信任所有主机,为了安全考虑,还是建议实现规范的处理。
如果我们需要做请求的会话保持,使用JHttp
可以很方便的添加Cookie
信息,在JRequest
中,我们提供了几个cookie
的重载方法,方便我们在请求之前添加cookie
信息。
因为JHttp
是基于HttpUrlConnection
的,所以全局的CookieManager
对于JHttp
同样有效。
CookieManager manager = new CookieManager();
CookieHandler.setDefault(manager);
JRequest.create("https://www.baidu.com").execute();
for (HttpCookie cookie : manager.getCookieStore().getCookies()) {
System.out.printf("%s=%s,domain=%s,path=%s\n",
cookie.getName(),
cookie.getValue(),
cookie.getDomain(),
cookie.getPath());
}
如果我们需要对请求添加日志等处理,我们可以实现com.jianggujin.http.core.JRequestExecuterListener
接口,该接口会在请求执行前与请求之行结束进行相关方法的回调,方便我们做日志记录等处理,在JHttp
中也提供了一个默认的日志实现类com.jianggujin.http.util.JRequestExecuterLog
,当然了,这个类仅仅是做了最简单的打印输出,我们只需要调用JRequestExecuter.setRequestExecuterListener(JRequestExecuterListener listener)
方法进行设置。
JHttp
除了上面的基本使用之外,还支持动态代理方式,通过定义API
接口配合提供的注解,可以更加方便快捷的完成请求处理。使用接口形式,我们首先需要定义请求的接口,举个例子:
@JBaseUrl("http://ws.webxml.com.cn")
public static interface Weather {
@JApiRequest(value = "/WebServices/WeatherWS.asmx/getWeather", method = JMethod.POST)
String weather(@JRequestParam("theCityCode") String theCityCode, @JRequestParam("theUserID") String theUserID);
}
定义完接口,我们需要使用JApiStore
获得接口的代理实现:
JApiStore.getApi(Weather.class).weather("2009", "");
接口方法中如果含有JResponse
、Proxy
、JSSLContextFactory
、JRequestBodyResolver
、JMethod
、JKeyVal
类型的参数,会直接将其设置在请求对象中。
设置API请求信息,用于设置请求路径
、方法
等信息,可以用在方法
上面。与JBaseUrl
搭配使用,会将域名与路径进行拼接。
请求体解析器,用于指定当前请求使用的请求体解析器
响应对象创建器,用于自定义创建接口方法的响应对象
请求地址,通常为域名,例如:http://www.baidu.com
,可以用在类
上面。
Cookie
当注解为类注解,则required()
无效, 会根据itemDelimiter()
与kvDelimiter()
的配置对value()
进行拆分
当注解为方法注解,则required()
无效, 会根据itemDelimiter()
与kvDelimiter()
的配置对value()
进行拆分
当注解为方法参数注解,则itemDelimiter()
与kvDelimiter()
的配置无效, 如果方法参数类型为String
,则value()
必须配置,对应值为Cookie名称,方法参数为Cookie值; 如果方法参数类型为Map
,则所有参数无效,方法参数即为Cookie数据
注解解析顺序为类注解 -> 方法注解 -> 方法参数注解。同名参数会覆盖
请求头
当注解为类注解,则required()
无效, 会根据itemDelimiter()
与kvDelimiter()
的配置对value()
进行拆分
当注解为方法注解,则required()
无效, 会根据itemDelimiter()
与kvDelimiter()
的配置对value()
进行拆分
当注解为方法参数注解,则itemDelimiter()
与kvDelimiter()
的配置无效, 如果方法参数类型为String
,则value()
必须配置,对应值为请求头名称,方法参数为请求头值; 如果方法参数类型为Map
,则所有参数无效,方法参数即为请求头
注解解析顺序为类注解 -> 方法注解 -> 方法参数注解。同名参数会覆盖
路径参数,路径参数形如{name}
String
,则value()
必须配置,对应值为路径参数名称,方法参数为路径参数值; 如果方法参数类型为Map
,则所有参数无效,方法参数即为路径参数数据请求参数,可以用在类
、方法
或方法参数
上面。当注解用在方法参数
上面的时候
String
,首先会判断value
是否为空串,是则注解参数用法相同,不是则value
为请求参数名称,参数值为对应请求参数的值Collection
或数组
,则仅有kvDelimiter
参数有效Map
则所有参数无效设置请求体,可以用在方法参数
上。
为了方便对响应数据的处理,JHttp
提供了一些默认的操作,在没有主动设置响应对象或响应对象创建器的情况下,则会根据方法返回值创建响应对象。
如果没有触发上述主动设置,JHttp
会首先通过JReturnTypeResponseFactory
创建需要的响应对象,想要让这部分生效,首先我们需要为JApiInvocationHandler
设置合适的JReturnTypeResponseFactory
实现。如果未设置JReturnTypeResponseFactory
或者该接口实现最终返回的响应对象为null
,那么,JHttp
会依据接口方法的返回数据类型设置对应的响应对象,支持的返回类型以及对应的相应处理类如下:
返回类型 | 响应类 |
---|---|
java.lang.String | JTextResponse |
byte[] | JByteResponse |
java.nio.ByteBuffer | JByteBufferResponse |
java.io.File | JFileResponse |
org.w3c.dom.Document | JXMLDomResponse |
其他 | JNoBodyResponse |
需要注意的是响应对象的
getData()
方法的返回值必须与接口方法返回值类型匹配,如果不匹配且返回类型为JResponse
,则会返回响应对象,否则会永远返回null
你可以在登录后,发表评论
点评 ( 3 )