cn.majingjing.http.client.handler.JdkHttpHandler Maven / Gradle / Ivy
The newest version!
package cn.majingjing.http.client.handler;
import cn.majingjing.http.client.exception.HttpClientException;
import cn.majingjing.http.client.request.HttpRequest;
import cn.majingjing.http.client.response.HttpResponse;
import cn.majingjing.http.client.util.HttpLogs;
import cn.majingjing.http.client.util.HttpUtils;
import cn.majingjing.http.client.util.ObjectUtils;
import cn.majingjing.http.client.util.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
/**
* JDK 方式的http处理类
*
* @author MaMarion
* @date 2020/5/1
*/
public class JdkHttpHandler implements HttpHandler {
@Override
public HttpResponse handleRequest(HttpRequest request) throws HttpClientException {
int maxRetry = request.getMaxRetry();
HttpResponse response = null;
do {
try {
//如果发生了重试, 记录重试次数
if (maxRetry < request.getMaxRetry()) {
HttpLogs.getLogger().warning(StringUtils.toStrings("try {} , {}", request.getMaxRetry() - maxRetry, request.getUrl()));
}
response = execute(request);
} catch (HttpClientException e) {
//如果重试次数用完了, 还是失败,则抛出此异常
if (maxRetry < 1) {
throw e;
}
}
//请求失败, 但是还未达到最大重试次数,继续发起请求
} while (callFailed(response) && maxRetry-- > 0);
return response;
}
/**
* 调用失败
*
* @param response 响应对象
* @return boolean
*/
private boolean callFailed(HttpResponse response) {
return response == null || !HttpUtils.isSuccess(response.getStatusCode());
}
/**
* 真实调用网络请求
*
* @param request http请求对象
* @return HttpResponse 响应对象
* @throws HttpClientException 调用出错将抛出http异常
*/
private HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpURLConnection connection;
try {
URL url = new URL(request.getUrl());
// 通过远程url连接对象打开一个连接,强转成httpURLConnection类
connection = (HttpURLConnection) url.openConnection();
// 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
connection.setDoInput(true);
// 设置请求方式
connection.setRequestMethod(request.getMethod());
// 设置连接主机服务器的超时时间
connection.setConnectTimeout(request.getConnectTimeout());
// 设置读取远程返回的数据超时时间
connection.setReadTimeout(request.getReadTimeout());
// 设置header信息
for (String name : request.getHeaders().keySet()) {
connection.setRequestProperty(name, request.getHeaders().get(name));
}
if (ObjectUtils.isNotNull(request.getBody())) {
// 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
connection.setDoOutput(true);
try (OutputStream os = connection.getOutputStream()) {
// 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
os.write(request.getBody());
}
}
// 发送请求(如果连接已经打开,则会忽略)
connection.connect();
return toHttpResponse(connection);
} catch (Exception e) {
throw new HttpClientException(request.getTraceId(),request.getUrl(), e);
}
}
/**
* 读取响应内容到响应对象中
*
* @param connection 链接通道
* @return HttpResponse 响应对象
* @throws IOException 读取响应失败则抛出IO异常
*/
private HttpResponse toHttpResponse(HttpURLConnection connection) throws IOException {
int statusCode = connection.getResponseCode();
Map> headers = connection.getHeaderFields();
byte[] body = transToBody(connection);
HttpClientException exception = null;
if (!HttpUtils.isSuccess(connection.getResponseCode())) {
exception = new HttpClientException(new String(body, StandardCharsets.UTF_8));
}
return new HttpResponse(statusCode, body, exception, headers);
}
/**
* 读取响应体
*
* @param connection 链接通道
* @return byte[] 响应体
* @throws IOException 读取响应失败则抛出IO异常
*/
private byte[] transToBody(HttpURLConnection connection) throws IOException {
InputStream is = null;
try {
if (HttpUtils.isSuccess(connection.getResponseCode())) {
// 通过connection连接,获取输入流
is = connection.getInputStream();
} else {
// 通过connection连接,获取输入流
is = connection.getErrorStream();
}
return HttpUtils.toByteArray(is);
} finally {
HttpUtils.close(is);
// 关闭远程连接
connection.disconnect();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy