com.gitee.apanlh.util.net.http.HttpExecutor Maven / Gradle / Ivy
package com.gitee.apanlh.util.net.http;
import com.gitee.apanlh.exp.HttpConnectionException;
import com.gitee.apanlh.exp.HttpException;
import com.gitee.apanlh.util.io.IOUtils;
import com.gitee.apanlh.util.net.http.handler.HttpInterceptor;
import com.gitee.apanlh.util.net.http.handler.HttpInterceptorContext;
import com.gitee.apanlh.util.net.http.io.HttpResponseInputStream;
import com.gitee.apanlh.util.net.http.log.HttpLog;
import com.gitee.apanlh.util.reflection.ClassTypeUtils;
import com.gitee.apanlh.web.http.HttpMethod;
/**
* HTTP执行器
*
如果需要实现一些请求前或请求后的操作可添加{@link HttpInterceptor}类
*
* @author Pan
*/
public class HttpExecutor {
/** HTTP客户端 */
private HttpClient httpClient;
/** HTTP请求对象 */
private HttpRequest httpRequest;
/** HTTP请求状态 */
private HttpStatus httpStatus;
/** HTTP日志 */
private HttpLog httpLog;
/** HTTP拦截器上下文 */
private HttpInterceptorContext httpInterceptorContext;
/** HTTP响应输入流 */
private HttpResponseInputStream httpResponseInputStream;
/**
* 默认构造函数
*
* @author Pan
*/
@SuppressWarnings("unused")
private HttpExecutor() {
// 不允许外部实例
super();
}
/**
* 构造-加载HTTPRequest
*
如果日志开启则创建HTTP日志
*
默认初始化HTTPClient首次URL值(不会创建连接)
*
* @author Pan
* @param httpRequest HTTP请求对象
* @param httpInterceptorContext 拦截器上下文
*/
HttpExecutor(HttpRequest httpRequest, HttpInterceptorContext httpInterceptorContext) {
this.httpRequest = httpRequest;
this.httpLog = HttpLog.create(httpRequest);
this.httpInterceptorContext = httpInterceptorContext;
this.httpClient = HttpClient.create(httpRequest.getUrl());
}
/**
* 执行-发送HTTP请求
*
不存在配置时根据请求类型来启动默认配置
*
出现异常将关闭客户端
*
* @author Pan
* @return HttpResponse
*/
public HttpResponse execute() {
httpInterceptorContext.getRequestPreInterceptorChain().proceed(httpRequest, httpClient);
httpInterceptorContext.getRequestInterceptorChain().proceed(httpRequest, httpClient);
try {
send();
HttpResponse httpResponse = new HttpResponse(httpRequest, httpStatus, httpClient, httpResponseInputStream, httpLog);
return httpInterceptorContext.getResponseInterceptorChain().proceed(httpResponse);
} catch (Exception e) {
IOUtils.close(httpClient, httpResponseInputStream);
throw new HttpConnectionException(e.getMessage(), e);
}
}
/**
* 写入请求
*
并不意味着数据已经被发送
*
写入过程如果出现异常,则会自动关闭流
*
* @author Pan
*/
private void write() throws HttpException {
HttpMethod method = httpRequest.getMethod();
HttpBody body = httpRequest.getBody();
HttpConfig config = httpRequest.getConfig();
httpLog.writeRequest();
// 如果消息为空则不写入
if (HttpMethod.GET.equals(method)
|| body == null
|| body.hasRest()
|| body.hasQueryParams()
|| body.getRequestBody() == null) {
return ;
}
Object data = body.getRequestBody();
if (ClassTypeUtils.isString(data)) {
IOUtils.write((String) data, httpClient.getOutputStream(), config.getCharset());
return ;
}
IOUtils.write((byte[]) data, httpClient.getOutputStream());
}
/**
* 发送请求,读取服务器的响应内容
*
* @author Pan
* @throws HttpException 出现异常则抛出
*/
private void send() throws HttpException {
write();
this.httpStatus = HttpStatus.create(httpClient);
this.httpLog.setHttpStatus(this.httpStatus);
this.httpResponseInputStream = httpClient.getInputStream(httpStatus);
}
/**
* 获取请求日志
*
* @author Pan
* @return HttpLog
*/
public HttpLog getHttpLog() {
return httpLog;
}
/**
* 构建-HTTP执行器
*
* @author Pan
* @param httpRequest HTTP请求对象
* @param httpInterceptorContext 拦截器上下文
* @return HttpExecutor
*/
public static HttpExecutor create(HttpRequest httpRequest, HttpInterceptorContext httpInterceptorContext) {
return new HttpExecutor(httpRequest, httpInterceptorContext);
}
}