top.jfunc.common.http.base.AbstractOkHttp3HttpTemplate Maven / Gradle / Ivy
package top.jfunc.common.http.base;
import okhttp3.*;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;
import top.jfunc.common.http.HttpStatus;
import top.jfunc.common.http.Method;
import top.jfunc.common.http.ParamUtil;
import top.jfunc.common.http.base.ssl.SSLSocketFactoryBuilder;
import top.jfunc.common.utils.ArrayListMultimap;
import top.jfunc.common.utils.IoUtil;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @author xiongshiyan at 2018/6/6
*/
public abstract class AbstractOkHttp3HttpTemplate extends AbstractConfigurableHttp implements HttpTemplate {
@Override
public R template(String url, Method method , String contentType , ContentCallback contentCallback , ArrayListMultimap headers, Integer connectTimeout, Integer readTimeout, String resultCharset , boolean includeHeaders , ResultCallback resultCallback) throws IOException{
Objects.requireNonNull(url);
Response response = null;
InputStream inputStream = null;
try {
String completedUrl = addBaseUrlIfNecessary(url);
//1.构造OkHttpClient
OkHttpClient.Builder clientBuilder = new OkHttpClient().newBuilder()
.connectTimeout(getConnectionTimeoutWithDefault(connectTimeout), TimeUnit.MILLISECONDS)
.readTimeout(getReadTimeoutWithDefault(readTimeout), TimeUnit.MILLISECONDS);
////////////////////////////////////ssl处理///////////////////////////////////
if(ParamUtil.isHttps(completedUrl)){
//默认设置这些
initSSL(clientBuilder , getHostnameVerifier() , getSSLSocketFactory() , getX509TrustManager());
}
////////////////////////////////////ssl处理///////////////////////////////////
//给子类复写的机会
doWithBuilder(clientBuilder , ParamUtil.isHttps(completedUrl));
OkHttpClient client = clientBuilder.build();
doWithClient(client);
//2.1设置URL
Request.Builder builder = new Request.Builder().url(completedUrl);
//2.2设置headers
setRequestHeaders(builder , contentType , mergeDefaultHeaders(headers));
//2.3处理请求体
if(null != contentCallback && method.hasContent()){
contentCallback.doWriteWith(builder);
}
//3.构造请求
Request request = builder.build();
//4.执行请求
response = client.newCall(request).execute();
//5.获取响应
// return getReturnMsg(response , resultCharset , includeHeaders , resultCallback);
inputStream = getStreamFrom(response , false);
int statusCode = response.code();
return resultCallback.convert(statusCode , inputStream, getResultCharsetWithDefault(resultCharset), includeHeaders ? parseHeaders(response) : new HashMap<>(0));
///保留起
/*if (HttpStatus.HTTP_OK == statusCode) {
convert = resultCallback.convert(HttpStatus.HTTP_OK , inputStream, resultCharset, includeHeaders ? parseHeaders(response) : new HashMap<>(0));
}else {
convert = resultCallback.convert(statusCode , inputStream , resultCharset , parseHeaders(response));
}
return convert;*/
} catch (IOException e) {
throw e;
} catch (Exception e){
throw new RuntimeException(e);
} finally {
IoUtil.close(inputStream);
IoUtil.close(response);
}
}
protected InputStream getStreamFrom(Response response , boolean ignoreResponseBody) {
//忽略返回body的情况下,直接返回空的
if(ignoreResponseBody){
return top.jfunc.common.http.IoUtil.emptyInputStream();
}
ResponseBody body = response.body();
InputStream inputStream = (body != null) ? body.byteStream() : top.jfunc.common.http.IoUtil.emptyInputStream();
if(null == inputStream){
inputStream = top.jfunc.common.http.IoUtil.emptyInputStream();
}
return inputStream;
}
protected void doWithBuilder(OkHttpClient.Builder builder , boolean isHttps) throws Exception{
//default do nothing, give children a chance to do more config
}
protected void doWithClient(OkHttpClient okHttpClient) throws Exception{
//default do nothing, give children a chance to do more config
}
/**
* @see SSLSocketFactoryBuilder#build()
* @see SSLSocketFactoryBuilder#build(String, String)
*/
protected void initSSL(OkHttpClient.Builder builder , HostnameVerifier hostnameVerifier , SSLSocketFactory sslSocketFactory , X509TrustManager trustManager) {
// 验证域
if(null != hostnameVerifier){
builder.hostnameVerifier(hostnameVerifier);
}
if(null != sslSocketFactory) {
builder.sslSocketFactory(sslSocketFactory , trustManager);
}
}
protected void setRequestBody(Request.Builder builder , Method method , RequestBody requestBody){
builder.method(method.name() , requestBody);
}
protected RequestBody stringBody(String body , String contentType){
MediaType mediaType = null;
if(null != contentType){
mediaType = MediaType.parse(contentType);
}
return RequestBody.create(mediaType, body);
}
protected RequestBody inputStreamBody(String contentType , InputStream inputStream , long length){
return new InputStreamRequestBody(contentType , inputStream , length);
}
protected R getReturnMsg(Response response , String resultCharset , boolean includeHeaders , ResultCallback resultParser) throws IOException {
int statusCode = response.code();
/*String body = new String(response.body().bytes() , resultCharset);*/
// if (HttpStatus.HTTP_OK == statusCode) {
// InputStream inputStream = response.body().byteStream();
// R convert = resultParser.convert(inputStream, resultCharset, includeHeaders ? parseHeaders(response) : new HashMap<>(0));
// IoUtil.close(inputStream);
// return convert;
//
// }else {
// //获取错误body,而不是仅仅状态行信息的message response.message()
// String errorMsg = new String(response.body().bytes() , resultCharset);
// throw new HttpException(statusCode,errorMsg,parseHeaders(response));
// }
InputStream inputStream = getStreamFrom(response , false);
R convert;
if (HttpStatus.HTTP_OK == statusCode) {
convert = resultParser.convert(HttpStatus.HTTP_OK , inputStream, resultCharset, includeHeaders ? parseHeaders(response) : new HashMap<>(0));
}else {
convert = resultParser.convert(statusCode , inputStream , resultCharset , parseHeaders(response));
}
IoUtil.close(inputStream);
return convert;
}
protected void setRequestHeaders(Request.Builder builder, String contentType, ArrayListMultimap headers) {
if(null != headers) {
Set keySet = headers.keySet();
keySet.forEach((k)->headers.get(k).forEach((v)->builder.addHeader(k,v)));
}
if(null != contentType){
builder.addHeader(top.jfunc.common.http.Header.CONTENT_TYPE.toString(), contentType);
}
}
/**
* 获取响应中的headers
*/
protected Map> parseHeaders(Response response) {
Headers resHeaders = response.headers();
ArrayListMultimap headers = new ArrayListMultimap<>(resHeaders.size());
resHeaders.names().forEach((key)-> headers.put(key,resHeaders.get(key)) );
return headers.getMap();
}
/**
* 根据inputStream生成requestBody的工具类
* @see RequestBody#create(MediaType, File)
*/
private static class InputStreamRequestBody extends RequestBody {
private String contentType;
private long len;
private InputStream stream;
public InputStreamRequestBody(String contentType, InputStream stream, long len) {
this.contentType = contentType;
this.stream = stream;
this.len = len;
}
@Override
public MediaType contentType() {
return MediaType.parse(contentType);
}
@Override
public long contentLength() throws IOException {
return len;
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = Okio.source(stream);
sink.writeAll(source);
IoUtil.close(stream);
IoUtil.close(source);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy