欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android-第三方框架-网络请求之okhttp

程序员文章站 2024-01-17 19:51:58
...

简介

OkHttp 是 Square 公司开源的针对 Java 和 Android 程序,封装的一个高性能 http 请求库,支持同步、异步,封装了线程池,封装了数据转换,封装了参数使用、错误处理等,api 使用起来更加方便。而且实现了spdy、http2、websocket协议。

应用

OkHttp 是基于http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient, HttpUrlConnection的职责是一样的。因此需要再封装一层。实现一行代码实现http请求。不多说,代码撸起来…

compile 'com.squareup.okhttp3:okhttp:3.8.1'
  • 支持https请求,添加cer证书
/**
     * 证书名称,https访问不同网站需要的cer证书
     * @param cername
     */
    HttpRequest(Context context,String cername) {
        httpBuilder = new OkHttpClient.Builder();
        if (cername != null)
            addSSL(context,cername);
    }


/**
     * 添加证书许可
     * 证书放在asset下
     * @param cerName 证书名称
     */
    public void addSSL(Context context,String cerName) {

        //获取证书数据
        InputStream zhengshu = null;
        try {
            zhengshu = context.getAssets().open(cerName);
            //设置验证当前的证书
            SSLSocketFactory sslSocketFactory = getSocketFactory(zhengshu);
            if (sslSocketFactory != null) {
                httpBuilder.sslSocketFactory(sslSocketFactory);
                httpBuilder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


/**
     * @param certificates 客户端添加的信任证书证书
     * @return 证书的SSLSock
     */
    private SSLSocketFactory getSocketFactory(InputStream... certificates) {
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));

                try {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e) {
                }
            }
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory =
                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
  • 服务器请求数据
/**
     * 带参数的服务交换数据
     * @param url
     * @param paramsMap
     * @param responseCallBack
     */
    public void requestAnsy(int httpType, String url, HashMap<String, Object> paramsMap, final HttpResponseCallBack responseCallBack) {

        final Request request = structRequest(httpType, url, paramsMap);
        new Thread(new Runnable() {
            @Override
            public void run() {
                defaultExcute(request, responseCallBack);
            }
        }).start();


    }


/**
     * 构建Request
     *
     * @param requestType
     * @param actionUrl
     * @param paramsMap
     * @return
     */
    private Request structRequest(int requestType, String actionUrl, HashMap<String, Object> paramsMap) {

        switch (requestType) {
            case TYPE_GET:
                actionUrl = getFullUrl(actionUrl, paramsMap);
                return new Request.Builder().url(actionUrl).build();

            case TYPE_POST:
                MultipartBody.Builder builder = new MultipartBody.Builder();
                if (paramsMap != null) {
                    for (String key : paramsMap.keySet()) {
                        Object object = paramsMap.get(key);
                        builder.addFormDataPart(key, object.toString());
                    }
                    RequestBody formBody = builder.build();
                    return new Request.Builder().url(actionUrl).post(formBody).build();
                } else {
                    return new Request.Builder().url(actionUrl).build();
                }

            default:
                return null;
        }

    }

    /**
     * get请求拼接url数据
     * url 添加参数
     *
     * @param paramsMap
     * @return
     */
    private String getFullUrl(String actionUrl, HashMap<String, Object> paramsMap) {
        if (paramsMap != null) {
            StringBuilder tempParams = new StringBuilder(actionUrl);
            try {
                //处理参数
                int pos = 0;
                for (String key : paramsMap.keySet()) {
                    if (pos > 0) {
                        tempParams.append("&");
                    }
                    //对参数进行URLEncoder
                    tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key).toString(), "utf-8")));
                    pos++;
                }
                //返回补全请求地址
                return tempParams.toString();
            } catch (Exception e) {
            }
        }
        return actionUrl;
    }
  • 请求结果回调
/**
     * 默认服务请求
     *
     * @param request
     * @param responseCallBack
     * @param <T>
     */
    private <T> void defaultExcute(Request request, HttpResponseCallBack responseCallBack) {
        String type = request.method();
        if (type.equalsIgnoreCase("Get")) {
            try {
                Response response = httpBuilder.build().newCall(request).execute();
                if (response.isSuccessful()) {
                    if (responseCallBack != null)
                        responseCallBack.onSuccess((T) response);
                } else {
                    if (responseCallBack != null)
                        responseCallBack.onFail(null);
                }

            } catch (IOException e) {
                e.printStackTrace();
                if (responseCallBack != null)
                    responseCallBack.onFail(e);
            }
        } else {
            runServiceExecute(request, responseCallBack);
        }
    }

    /**
     * 执行服务post请求
     * @param request
     * @param responseCallBack
     */
    private<T> void runServiceExecute(Request request,final HttpResponseCallBack responseCallBack) {

        httpBuilder.build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (responseCallBack != null)
                    responseCallBack.onFail(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    if (responseCallBack != null)
                        responseCallBack.onSuccess((T) response);
                } else {
                    if (responseCallBack != null)
                        responseCallBack.onFail(null);
                }
            }

        });
    }

完整代码


import android.content.Context;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.util.HashMap;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 与服务器之间数据的交互,
 * Created by gm on 2017/3/9.
 */

public class HttpRequest {

    private OkHttpClient.Builder httpBuilder;       //okHttpClient 实例

    public static final int TYPE_GET = 0;
    public static final int TYPE_POST = 1;


    /**
     * 证书名称,https访问不同网站需要的cer证书
     * @param cername
     */
    HttpRequest(Context context,String cername) {
        httpBuilder = new OkHttpClient.Builder();
        if (cername != null)
            addSSL(context,cername);
    }

    /**
     * 添加证书许可
     * 证书放在asset下
     * @param cerName 证书名称
     */
    public void addSSL(Context context,String cerName) {

        //获取证书数据
        InputStream zhengshu = null;
        try {
            zhengshu = context.getAssets().open(cerName);
            //设置验证当前的证书
            SSLSocketFactory sslSocketFactory = getSocketFactory(zhengshu);
            if (sslSocketFactory != null) {
                httpBuilder.sslSocketFactory(sslSocketFactory);
                httpBuilder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param certificates 客户端添加的信任证书证书
     * @return 证书的SSLSock
     */
    private SSLSocketFactory getSocketFactory(InputStream... certificates) {
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));

                try {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e) {
                }
            }
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory =
                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 带参数的服务交换数据
     * @param url
     * @param paramsMap
     * @param responseCallBack
     */
    public void requestAnsy(int httpType, String url, HashMap<String, Object> paramsMap, final HttpResponseCallBack responseCallBack) {

        final Request request = structRequest(httpType, url, paramsMap);
        new Thread(new Runnable() {
            @Override
            public void run() {
                defaultExcute(request, responseCallBack);
            }
        }).start();


    }

    /**
     * 构建Request
     *
     * @param requestType
     * @param actionUrl
     * @param paramsMap
     * @return
     */
    private Request structRequest(int requestType, String actionUrl, HashMap<String, Object> paramsMap) {

        switch (requestType) {
            case TYPE_GET:
                actionUrl = getFullUrl(actionUrl, paramsMap);
                return new Request.Builder().url(actionUrl).build();

            case TYPE_POST:
                MultipartBody.Builder builder = new MultipartBody.Builder();
                if (paramsMap != null) {
                    for (String key : paramsMap.keySet()) {
                        Object object = paramsMap.get(key);
                        builder.addFormDataPart(key, object.toString());
                    }
                    RequestBody formBody = builder.build();
                    return new Request.Builder().url(actionUrl).post(formBody).build();
                } else {
                    return new Request.Builder().url(actionUrl).build();
                }

            default:
                return null;
        }

    }

    /**
     * get请求拼接url数据
     * url 添加参数
     *
     * @param paramsMap
     * @return
     */
    private String getFullUrl(String actionUrl, HashMap<String, Object> paramsMap) {
        if (paramsMap != null) {
            StringBuilder tempParams = new StringBuilder(actionUrl);
            try {
                //处理参数
                int pos = 0;
                for (String key : paramsMap.keySet()) {
                    if (pos > 0) {
                        tempParams.append("&");
                    }
                    //对参数进行URLEncoder
                    tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key).toString(), "utf-8")));
                    pos++;
                }
                //返回补全请求地址
                return tempParams.toString();
            } catch (Exception e) {
            }
        }
        return actionUrl;
    }

    /**
     * 默认服务请求
     *
     * @param request
     * @param responseCallBack
     * @param <T>
     */
    private <T> void defaultExcute(Request request, HttpResponseCallBack responseCallBack) {
        String type = request.method();
        if (type.equalsIgnoreCase("Get")) {
            try {
                Response response = httpBuilder.build().newCall(request).execute();
                if (response.isSuccessful()) {
                    if (responseCallBack != null)
                        responseCallBack.onSuccess((T) response);
                } else {
                    if (responseCallBack != null)
                        responseCallBack.onFail(null);
                }

            } catch (IOException e) {
                e.printStackTrace();
                if (responseCallBack != null)
                    responseCallBack.onFail(e);
            }
        } else {
            runServiceExecute(request, responseCallBack);
        }
    }

    /**
     * 执行服务post请求
     * @param request
     * @param responseCallBack
     */
    private<T> void runServiceExecute(Request request,final HttpResponseCallBack responseCallBack) {

        httpBuilder.build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (responseCallBack != null)
                    responseCallBack.onFail(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    if (responseCallBack != null)
                        responseCallBack.onSuccess((T) response);
                } else {
                    if (responseCallBack != null)
                        responseCallBack.onFail(null);
                }
            }

        });
    }

}
  • 回调接口
public interface HttpResponseCallBack{

    /**
     * success on response,return response
     * @param result
     */
    <T> void onSuccess(T result);

    /**
     * faile on response ,if e is null,which the service is noconnect,
     * @param e
     */
    void onFail(Exception e);
}

应用

new HttpRequest(getApplicationContext(),null).requestAnsy(HttpRequest.TYPE_GET,url, null, new HttpResponseCallBack() {
            @Override
            public <T> void onSuccess(T result) {
                Response resultRes = (Response)result;
                .......
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFail(Exception e) {

            }
        });

最后记得在AndroidManifest.xml添加网络访问权限:

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
相关标签: android