OkHttpUtils.java 6.15 KB
package com.huaheng.common.utils.http;


import com.google.gson.Gson;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.aspectj.ApiLogAspect;
import com.huaheng.pc.monitor.apilog.domain.ApiLog;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * OkHttp发送请求
 * @author huaheng
 * @Date 2022-5-30
 */
public class OkHttpUtils {

    private static final Logger log = LoggerFactory.getLogger(OkHttpUtils.class);

    /**
     * 最大连接时间
     */
    public final static int CONNECTION_TIMEOUT = 10;
    /**
     * JSON格式
     */
    public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
    /**
     * OkHTTP线程池最大空闲线程数
     */
    public final static int MAX_IDLE_CONNECTIONS = 100;
    /**
     * OkHTTP线程池空闲线程存活时间
     */
    public final static long KEEP_ALIVE_DURATION = 30L;


    private static final String CONTENT_TYPE = "Content-Type";


    /**
     * client
     * 配置重试
     */
    private final static OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder()
            .connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
            .connectionPool(new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_DURATION, TimeUnit.MINUTES))
            .build();
    private static final Gson GSON = new Gson();

    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url 发送请求的 URL
    //* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url,String param)
    {
        //headers  请求头
        Map<String, String> headers=new HashMap<>();
        //请求URI
        String urlNameString = url + "?" + param;

        Request.Builder builder = new  Request.Builder();
        buildHeader(builder, headers);

        Request request = builder.url(urlNameString).get().build();
        Response response = null;
        try {
            response = HTTP_CLIENT.newCall(request).execute();
            if (response.isSuccessful() && Objects.nonNull(response.body())) {
                String result = response.body().string();
                log.info("执行get请求, url: {} 成功,返回数据: {}", url, result);
                return result;
            }
        } catch (IOException e) {
            log.error("执行get请求,url: {} 失败!", url, e);
        }
        return "";
    }



    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url 发送请求的 URL
    // * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param){
        FormBody.Builder builder = new FormBody.Builder();
        String urlNameString = url + "?" + param;
        FormBody body = builder.build();
        Request request = new Request
                .Builder()
                .url(urlNameString)
                .post(body)
                .build();
        Response response = null;
        try {
            response = HTTP_CLIENT.newCall(request).execute();
            //调用成功
            if (response.isSuccessful() && response.body() != null) {
                return response.body().string();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }


    //此方法是将参数以body形式发送post请求
    public static String bodypost(String strURL, String json,String warehouseCode) {
        ApiLog apiLog = null;
        // using above json body as a input to post API call
        RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json);
        //headers  请求头
        Map<String, String> headers =new HashMap<>();
        headers.put("Accept","application/json");// 设置接收数据的格式
        headers.put("Content-Type","application/json");// 设置发送数据的格式
        Request.Builder builder = new Request.Builder();
        buildHeader(builder, headers);
        Request request = builder.url(strURL).post(body).build();
        Response response = null;
        String result=null;
        try {
            apiLog = ApiLogAspect.initApiLog(request, json, warehouseCode);
            response = HTTP_CLIENT.newCall(request).execute();
            if (response.isSuccessful() && Objects.nonNull(response.body())) {
                result = response.body().string();
                log.info("执行post请求,url: {}, header: {} ,参数: {} 成功,返回结果: {}", strURL, headers, json, result);
            }
        } catch (IOException e) {
            ApiLogAspect.setApiLogException(apiLog, e);
            log.error("执行post请求,url: {},参数: {} 失败!", strURL, json, e);
        } finally {
            ApiLogAspect.finishApiLog(apiLog, response, result);
        }
        return result;
    }

    /**
     * 设置请求头
     *
     * @param builder .
     * @param headers 请求头
     */
    private static void buildHeader(Request.Builder builder, Map<String, String> headers) {
        if (Objects.nonNull(headers) && headers.size() > 0) {
            headers.forEach((k, v) -> {
                if (Objects.nonNull(k) && Objects.nonNull(v)) {
                    builder.addHeader(k, v);
                }
            });
        }
    }

    /**
     * 支持嵌套泛型的post请求。
     * <pre>
     *   Type type = new TypeToken<Results<User>>() {}.getType();
     * <pre/>
     *
     * @param url     链接
     * @param json    请求json
     * @param type    嵌套泛型
     * @return 响应对象, 可进行强转。
     */
    public static <T> T post(String url, String json, Type type) {
        String result = bodypost(url, json, ShiroUtils.getWarehouseCode());
        if (Objects.nonNull(result) && Objects.nonNull(type)) {
            return GSON.fromJson(result, type);
        }
        return null;
    }
}