All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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