OkHttp工具類


 

package com.lonely.utils;

import com.ztkj.common.log.interceptors.HttpLogInterceptor;
import okhttp3.*;
import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author lonely
 * @Date 2019/9/2 14:05
 * @Description 基於okhttp的工具類
 */
public class OkHttpUtil {

    private static final Logger logger = LoggerFactory.getLogger(OkHttpUtil.class);

    public final static int READ_TIMEOUT = 100;
    public final static int CONNECT_TIMEOUT = 60;
    public final static int WRITE_TIMEOUT = 60;
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

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

    private static final byte[] LOCKER = new byte[0];
    private static OkHttpUtil mInstance;
    private OkHttpClient mOkHttpClient;


    private OkHttpUtil() {
        //todo 由於是靜態工具類,只會創建client一次,如果以后需要不同請求不同超時時間,不能這樣使用
        okhttp3.OkHttpClient.Builder clientBuilder = new okhttp3.OkHttpClient.Builder();
        //設置讀取超市時間
        clientBuilder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
        //設置超時連接時間
        clientBuilder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
        //設置寫入超時時間
        clientBuilder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS);
        //支持HTTPS請求,跳過證書驗證
        clientBuilder.sslSocketFactory(createSSLSocketFactory());
        clientBuilder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

        //添加攔截器
        clientBuilder.addInterceptor(new HttpLogInterceptor());
        mOkHttpClient = clientBuilder.build();
    }

    /**
     * 單例模式獲取NetUtils
     *
     * @return
     */
    public static OkHttpUtil getInstance() {
        if (mInstance == null) {
            synchronized (LOCKER) {
                if (mInstance == null) {
                    mInstance = new OkHttpUtil();
                }
            }
        }
        return mInstance;
    }


    /**
     * get請求,同步方式,獲取網絡數據,是在主線程中執行的,需要新起線程,將其放到子線程中執行
     *
     * @param url
     * @return
     */
    public Response getData(String url) {
        return getData(url, null);
    }


    /**
     * get請求,同步方式,獲取網絡數據,是在主線程中執行的,需要新起線程,將其放到子線程中執行
     *
     * @param url
     * @return
     */
    public Response getData(String url, Map<String, String> headerMap) {
        //1 構造Request
        Request.Builder builder = new Request.Builder().get().url(url);
        //Request request = builder.get().url(url).build();
        //builder = builder.get().url(url);
        /*if (headerMap != null && headerMap.isEmpty()) {
            for (Map.Entry<String, String> headerEntry : headerMap.entrySet()) {
                builder.addHeader(headerEntry.getKey(), headerEntry.getValue());
            }
        }*/
        addHeaders(headerMap,builder);
        Request request = builder.build();


        //2 將Request封裝為Call
        Call call = mOkHttpClient.newCall(request);
        //3 執行Call,得到response
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    /**
     * post form表單 請求,同步方式,提交數據,是在主線程中執行的,需要新起線程,將其放到子線程中執行
     *
     * @param url
     * @param bodyParams
     * @return
     */
    /*public Response postFormData(String url, Map<String, String> bodyParams) {
        //1構造RequestBody
        RequestBody body = setRequestBody(bodyParams);
        //2 構造Request
        Request.Builder requestBuilder = new Request.Builder();
        Request request = requestBuilder.post(body).addHeader(CONTENT_TYPE, HttpContentTypeEnum.FORM.contentTypeValue).url(url).build();
        //3 將Request封裝為Call
        Call call = mOkHttpClient.newCall(request);
        //4 執行Call,得到response
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }*/

    /**
     * post方式
     *
     * @param url        請求url
     * @param bodyParams requestbody
     * @param headerMap  請求頭信息
     * @return
     * @throws IOException
     */
    public Response postData(String url, Map<String, Object> bodyParams, Map<String, String> headerMap) throws Exception {
        //1構造RequestBody
        RequestBody body = setRequestBody(bodyParams, headerMap);
        //2 構造Request
        Request.Builder requestBuilder = new Request.Builder().post(body).url(url);
        //requestBuilder = requestBuilder.post(body).url(url);
        addHeaders(headerMap, requestBuilder);
        Request request = requestBuilder.build();
        //Request request = requestBuilder.post(body).addHeader(CONTENT_TYPE, HttpContentTypeEnum.JSON.contentTypeValue).url(url).build();
        //3 將Request封裝為Call
        Call call = mOkHttpClient.newCall(request);
        //4 執行Call,得到response
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }


    /**
     * put請求方式
     *
     * @param url
     * @param bodyParams
     * @return
     */
    public Response putData(String url, Map<String, Object> bodyParams, Map<String, String> headerMap) throws Exception {
        //1構造RequestBody
        RequestBody body = setRequestBody(bodyParams, headerMap);
        //2 構造Request
        Request.Builder requestBuilder = new Request.Builder().put(body).url(url);
        addHeaders(headerMap, requestBuilder);
        Request request = requestBuilder.build();
        //3 將Request封裝為Call
        Call call = mOkHttpClient.newCall(request);
        //4 執行Call,得到response
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;

    }


    /**
     * @param url
     * @param bodyParams
     * @return
     */
    public Response delData(String url, Map<String, Object> bodyParams, Map<String, String> headerMap) throws Exception {
        //1構造RequestBody
        RequestBody body = setRequestBody(bodyParams, headerMap);
        //2 構造Request
        Request.Builder requestBuilder = new Request.Builder().delete(body).url(url);
        addHeaders(headerMap, requestBuilder);
        Request request = requestBuilder.build();
        //3 將Request封裝為Call
        Call call = mOkHttpClient.newCall(request);
        //4 執行Call,得到response
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }


    /**
     * post的請求參數,構造RequestBody
     *
     * @param bodyParams
     * @return
     */
    private RequestBody setRequestBody(Map<String, Object> bodyParams, Map<String, String> headerMap) throws Exception {
        //判斷請求頭中是否存在 content-type字段
        if (headerMap == null || !headerMap.containsKey(CONTENT_TYPE)) {
            throw new Exception("請求頭信息配置中無 Content-Type配置,請先配置");
        }

        String contentType = headerMap.get(CONTENT_TYPE);
        if ("application/x-www-form-urlencoded".equals(contentType)) {
            //表單提交 就是key-value 都是字符串型
            //轉換
            Map<String, String> strBodyParamMap = new HashMap<>();
            if (bodyParams != null && !bodyParams.isEmpty()) {
                bodyParams.forEach((key, value) -> {
                    if (value != null) {
                        strBodyParamMap.put(key, (String) value);
                    }
                });
            }
            return buildRequestBodyByMap(strBodyParamMap);
        } else {
            //json
            return buildRequestBodyByJson(com.alibaba.fastjson.JSON.toJSONString(bodyParams));
        }

    }

    /**
     * 表單方式提交構建
     *
     * @param bodyParams
     * @return
     */
    private RequestBody buildRequestBodyByMap(Map<String, String> bodyParams) {
        RequestBody body = null;
        okhttp3.FormBody.Builder formEncodingBuilder = new okhttp3.FormBody.Builder();
        if (bodyParams != null) {
            Iterator<String> iterator = bodyParams.keySet().iterator();
            String key = "";
            while (iterator.hasNext()) {
                key = iterator.next().toString();
                formEncodingBuilder.add(key, bodyParams.get(key));
                logger.info(" 請求參數:{},請求值:{} ", key, bodyParams.get(key));
            }
        }
        body = formEncodingBuilder.build();
        return body;
    }

    /**
     * json方式提交構建
     *
     * @param jsonStr
     * @return
     */
    private RequestBody buildRequestBodyByJson(String jsonStr) {
        return RequestBody.create(JSON, jsonStr);
    }


    /**
     * 生成安全套接字工廠,用於https請求的證書跳過
     *
     * @return
     */
    public SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
        }
        return ssfFactory;
    }


    /**
     * 針對json post處理
     *
     * @param url
     * @param json
     * @return
     * @throws IOException
     */
    public String postJson(String url, String json) throws IOException {
        RequestBody body = RequestBody.create(JSON, json);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Response response = mOkHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            return response.body().string();
        } else {
            throw new IOException("Unexpected code " + response);
        }
    }

    public void postJsonAsyn(String url, String json, final MyNetCall myNetCall) throws IOException {
        RequestBody body = RequestBody.create(JSON, json);
        //2 構造Request
        Request.Builder requestBuilder = new Request.Builder();
        Request request = requestBuilder.post(body).url(url).build();
        //3 將Request封裝為Call
        Call call = mOkHttpClient.newCall(request);
        //4 執行Call
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                myNetCall.failed(call, e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                myNetCall.success(call, response);

            }
        });
    }

    /**
     * 自定義網絡回調接口
     */
    public interface MyNetCall {
        void success(Call call, Response response) throws IOException;

        void failed(Call call, IOException e);
    }

    /**
     * 構建http get請求,將參數拼接到url后面
     *
     * @param url
     * @param para
     * @return
     * @throws URISyntaxException
     * @throws MalformedURLException
     */
    public static String buildHttpGet(String url, Map<String, Object> para)
            throws URISyntaxException, MalformedURLException {
        URIBuilder builder = new URIBuilder(url);
        Set<String> set = para.keySet();
        for (String key : set) {
            builder.setParameter(key, String.valueOf(para.get(key)));
        }
        return builder.build().toURL().toString();
    }


    /**
     * 添加header信息
     *
     * @param headerMap
     * @param builder
     * @return
     */
    private static Request.Builder addHeaders(Map<String, String> headerMap, Request.Builder builder) {
        if (headerMap != null && !headerMap.isEmpty()) {
            headerMap.forEach((key, value) -> builder.addHeader(key, value));
        }
        return builder;
    }

    /**
     * 用於信任所有證書
     */
    class TrustAllCerts implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM