net.lulihu.http.builder.HttpBuilder Maven / Gradle / Ivy
package net.lulihu.http.builder;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.lulihu.ObjectKit.FileKit;
import net.lulihu.ObjectKit.MapKit;
import okhttp3.*;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* http构建类
*
* 注意:发送完请求后如果不需要对响应结果进行处理需要调用 close()方法来关闭响应链接
*/
@Slf4j
public abstract class HttpBuilder {
/**
* 请求路径
*/
protected final String url;
/**
* 请求头构建
*/
protected Headers.Builder headerBuilder;
/**
* http 请求客户端构建
*/
protected OkHttpClient.Builder httpClientBuilder;
/**
* 请求对象构建
*/
protected Request.Builder requestBuilder;
/**
* 请求结果
*/
protected ResponseBody responseBody;
public HttpBuilder(String url) {
this.url = url;
this.headerBuilder = new Headers.Builder();
this.httpClientBuilder = new OkHttpClient.Builder();
this.requestBuilder = new Request.Builder();
if (log.isDebugEnabled())
httpClientBuilder.addInterceptor(new RequestLogInterceptor());
}
/**
* 准备发送get请求
*
* @param url 请求地址
* @return {@linkplain HttpGetBuilder}
*/
public static HttpGetBuilder get(String url) {
return new HttpGetBuilder(url);
}
/**
* 准备发送Post请求
*
* @param url 请求地址
* @return {@linkplain HttpPostBuilder}
*/
public static HttpPostBuilder post(String url) {
return new HttpPostBuilder(url);
}
/**
* 准备发送Post Payload 有效载荷请求
*
* @param url 请求地址
* @return {@linkplain HttpPostPayloadBuilder}
*/
public static HttpPostPayloadBuilder postPayload(String url) {
return new HttpPostPayloadBuilder(url);
}
/**
* 准备发送 post 多部分分片请求
*
* @param url 请求地址
* @return {@linkplain HttpPostMultipartBuilder}
*/
public static HttpPostMultipartBuilder postMultipart(String url) {
return new HttpPostMultipartBuilder(url);
}
/**
* 添加网络层拦截器
*
* @param interceptor 网络层拦截器
* @return {@linkplain HttpBuilder}
*/
public HttpBuilder addNetInterceptor(Interceptor interceptor) {
httpClientBuilder.addNetworkInterceptor(interceptor);
return this;
}
/**
* 添加请求拦截器
*
* @param requestInterceptor 请求拦截器
* @return {@linkplain HttpBuilder}
*/
public HttpBuilder addRequestInterceptor(RequestInterceptor requestInterceptor) {
httpClientBuilder.addInterceptor(requestInterceptor);
return this;
}
/**
* 添加响应拦截器
*
* @param responseInterceptor 响应拦截器
* @return {@linkplain HttpBuilder}
*/
public HttpBuilder addResponseInterceptor(ResponseInterceptor responseInterceptor) {
httpClientBuilder.addInterceptor(responseInterceptor);
return this;
}
/**
* 设置请求头信息
*
* @param header 头部信息
* @return {@linkplain HttpBuilder}
*/
public HttpBuilder setHeader(Map header) {
if (MapKit.isEmpty(header)) throw new NullPointerException("设置的请求头部信息不可以为空");
// 循环保存
for (Map.Entry entry : header.entrySet()) {
this.headerBuilder.add(entry.getKey(), entry.getValue());
}
return this;
}
/**
* 添加请求头信息
*
* @param key 键
* @param value 值
* @return {@linkplain HttpBuilder}
*/
public HttpBuilder addHeader(String key, String value) {
this.headerBuilder.add(key, value);
return this;
}
/**
* 设置连接超时时间
*
* @param timeout 超时时间
* @param unit 时间单位
* @return {@linkplain HttpBuilder}
*/
public HttpBuilder setConnectTimeout(long timeout, TimeUnit unit) {
this.httpClientBuilder.connectTimeout(timeout, unit);
return this;
}
/**
* 设置读取超时时间
*
* @param timeout 超时时间
* @param unit 时间单位
* @return {@linkplain HttpBuilder}
*/
public HttpBuilder setReadTimeout(long timeout, TimeUnit unit) {
this.httpClientBuilder.readTimeout(timeout, unit);
return this;
}
/**
* 发送请求
*
* @throws HttpRequestException 请求出现例外
*/
protected final void sendRequest() throws HttpRequestException {
// 设置请求头
requestBuilder.headers(headerBuilder.build());
// 构建请求对象
Request request = requestBuilder.build();
// 构建请求客户端
OkHttpClient httpClient = httpClientBuilder.build();
try {
// 执行请求
Response response = httpClient.newCall(request).execute();
// 请求失败
if (!response.isSuccessful()) {
throw new HttpRequestException(response.code(), response.message(), response.body() == null ? "" : response.body().string());
}
//请求响应结果
this.responseBody = response.body();
} catch (IOException e) {
throw new HttpRequestException(e, "请求 [{}] 发生例外", request.url().toString());
}
}
/**
* 关闭响应体
*
* 如果只发送请求,不对请求结果进行处理 记得只send方法后执行该方法
*/
public void close() {
responseBody.close();
}
/**
* 获取字节流
*
* @return 字节流
*/
public InputStream byteStream() {
try {
return responseBody.byteStream();
} finally {
close();
}
}
/**
* 数据写入文件
*
* @param file 文件 不存在则创建
* @throws IOException 操作过程发生例外
*/
public void writeFile(File file) throws IOException {
try (BufferedSource source = responseBody.source();
BufferedSink sink = Okio.buffer(Okio.sink(FileKit.createFile(file)))) {
sink.writeAll(source);
sink.flush();
} finally {
close();
}
}
/**
* 获取请求结果
*
* @return 请求结果
* @throws IOException 响应主体转换为字符串发生例外
*/
public String getResult() throws IOException {
try {
return responseBody.string();
} finally {
close();
}
}
/**
* 获取json obj 结果
*
* @param resultClass 返回值封装对象
* @param 泛型
* @return T
* @throws IOException 响应主体转换为字符串发生例外
*/
public T getJsonObjResult(Class resultClass) throws IOException {
String result = getResult();
if (result == null) return null;
return JSON.parseObject(result, resultClass);
}
/**
* 获取json array 结果
*
* @param resultClass 返回值封装对象
* @param 泛型
* @return List
* @throws IOException 响应主体转换为字符串发生例外
*/
public List getJsonArrayResult(Class resultClass) throws IOException {
String result = getResult();
if (result == null) return null;
return JSON.parseArray(result, resultClass);
}
}