android网络访问之HttpURLConnection vs OkHttp

来源:互联网 发布:淘宝电子商务模式分析 编辑:程序博客网 时间:2024/05/18 08:24

首先HttpURLConnection是原生的android网络访问的API,而OkHttp则是第三方的包;

其次,测试发现这两种方法,如果是广泛认可的证书所认证的https网址,可以正常获取到,如果是比较小众的,也就是相当于代码里没有备案的证书,则访问不到。

1、HttpURLConnection的使用:

<1>基本用法:

package zjava.data.request;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLEncoder;import java.util.HashMap;import zjava.sysutil.Common;import android.util.Log;/** * 原生的网络请求 * 使用网络类必须要在Manifest里面添加: * <uses-permission android:name="android.permission.INTERNET" /> * @author wzj * */public class HttpUrlConn {public static void requestGet(String baseUrl,HashMap<String, String> paramsMap) {// 如果有参数的话,并且忘记了?则给加上if(baseUrl != null && !baseUrl.endsWith("?") && !paramsMap.isEmpty())baseUrl = baseUrl+"?";HttpUrlConn conn = new HttpUrlConn();new Thread(conn.new HttpRequestGetRunnable(baseUrl, paramsMap)).start();    }public static void requestPost(String baseUrl,HashMap<String, String> paramsMap) {        HttpUrlConn conn = new HttpUrlConn();        new Thread(conn.new HttpRequestPostRunnable(baseUrl, paramsMap)).start();    }/**     * 将输入流转换成字符串     *     * @param is 从网络获取的输入流     * @return     */    public static String streamToString(InputStream is) {        try {            ByteArrayOutputStream baos = new ByteArrayOutputStream();            byte[] buffer = new byte[1024];            int len = 0;            while ((len = is.read(buffer)) != -1) {                baos.write(buffer, 0, len);            }            baos.close();            is.close();            byte[] byteArray = baos.toByteArray();            return new String(byteArray);        } catch (Exception e) {            Log.v(Common.MSG_ZJAVA, e.toString());            return null;        }    }        class HttpRequestGetRunnable implements Runnable    {    private String baseUrl;    private HashMap<String, String> paramsMap;        public HttpRequestGetRunnable(String baseUrl,HashMap<String, String> paramsMap)    {    this.baseUrl = baseUrl;    this.paramsMap = paramsMap;    }    @Overridepublic void run() {try{StringBuilder tempParams = new StringBuilder();            int pos = 0;            for (String key : paramsMap.keySet()) {                if (pos > 0) {                    tempParams.append("&");                }                tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key),"utf-8")));                pos++;            }            String requestUrl = baseUrl + tempParams.toString();            // 新建一个URL对象            URL url = new URL(requestUrl);            // 打开一个HttpURLConnection连接            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();            // 设置连接主机超时时间            urlConn.setConnectTimeout(5 * 1000);            //设置从主机读取数据超时            urlConn.setReadTimeout(5 * 1000);            // 设置是否使用缓存  默认是true            urlConn.setUseCaches(true);            // 设置为Post请求            urlConn.setRequestMethod("GET");            //urlConn设置请求头信息            //设置请求中的媒体类型信息。            //urlConn.setRequestProperty("Content-Type", "application/json");            //设置客户端与服务连接类型            urlConn.addRequestProperty("Connection", "Keep-Alive");            // 开始连接            urlConn.connect();            // 判断请求是否成功            if (urlConn.getResponseCode() == 200) {                // 获取返回的数据                String result = streamToString(urlConn.getInputStream());                Log.v(Common.MSG_ZJAVA, "Get方式请求成功,result--->" + result);            } else {                Log.v(Common.MSG_ZJAVA, "Get方式请求失败");            }            // 关闭连接            urlConn.disconnect();}catch(Exception e){Log.v(Common.MSG_ZJAVA, e.toString());}}        }        class HttpRequestPostRunnable implements Runnable    {    private String baseUrl;    private HashMap<String, String> paramsMap;            public HttpRequestPostRunnable(String baseUrl,HashMap<String, String> paramsMap)    {    this.baseUrl = baseUrl;    this.paramsMap = paramsMap;    }    @Overridepublic void run() {try {            //合成参数            StringBuilder tempParams = new StringBuilder();            int pos = 0;            for (String key : paramsMap.keySet()) {                if (pos > 0) {                    tempParams.append("&");                }                tempParams.append(String.format("%s=%s", key,  URLEncoder.encode(paramsMap.get(key),"utf-8")));                pos++;            }            String params =tempParams.toString();            // 请求的参数转换为byte数组            byte[] postData = params.getBytes();            // 新建一个URL对象            URL url = new URL(baseUrl);            // 打开一个HttpURLConnection连接            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();            // 设置连接超时时间            urlConn.setConnectTimeout(5 * 1000);            //设置从主机读取数据超时            urlConn.setReadTimeout(5 * 1000);            // Post请求必须设置允许输出 默认false            urlConn.setDoOutput(true);            //设置请求允许输入 默认是true            urlConn.setDoInput(true);            // Post请求不能使用缓存            urlConn.setUseCaches(false);            // 设置为Post请求            urlConn.setRequestMethod("POST");            //设置本次连接是否自动处理重定向            urlConn.setInstanceFollowRedirects(true);            // 配置请求Content-Type            //urlConn.setRequestProperty("Content-Type", "application/json");            // 开始连接            urlConn.connect();            // 发送请求参数            DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());            dos.write(postData);            dos.flush();            dos.close();            // 判断请求是否成功            if (urlConn.getResponseCode() == 200) {                // 获取返回的数据                String result = streamToString(urlConn.getInputStream());                Log.v(Common.MSG_ZJAVA, "Post方式请求成功,result--->" + result);            } else {                Log.v(Common.MSG_ZJAVA, "Post方式请求失败");            }            // 关闭连接            urlConn.disconnect();        } catch (Exception e) {            Log.v(Common.MSG_ZJAVA, e.toString());        }}        }}



这里参考了大神的文章,原文链接:

http://www.cnblogs.com/whoislcj/p/5520384.html


调用:

HttpUrlConn.requestPost("http://yourdomain.com/push_url", new HashMap<String, String>());//post调用不带参数也要new一个map

get也一样,把函数换成requestGet就可以了。


<2>封装并且添加https支持

package zjava.data.request;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLEncoder;import java.security.SecureRandom;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import java.util.HashMap;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSession;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;import zjava.sysutil.Common;import android.os.Handler;import android.os.Looper;import android.util.Log;/** * 原生的网络请求 * 使用网络类必须要在Manifest里面添加: * <uses-permission android:name="android.permission.INTERNET" /> * @author wzj * */public class HttpUrlConn {public static void requestGet(String baseUrl,HashMap<String, String> paramsMap,ResultCallback callback) {// 如果有参数的话,并且忘记了?则给加上if(baseUrl != null && !baseUrl.endsWith("?") && !paramsMap.isEmpty())baseUrl = baseUrl+"?";HttpUrlConn conn = new HttpUrlConn();new Thread(conn.new HttpRequestGetRunnable(baseUrl, paramsMap,callback)).start();    }public static void requestPost(String baseUrl,HashMap<String, String> paramsMap,ResultCallback callback) {        HttpUrlConn conn = new HttpUrlConn();        new Thread(conn.new HttpRequestPostRunnable(baseUrl, paramsMap,callback)).start();    }/**     * 将输入流转换成字符串     *     * @param is 从网络获取的输入流     * @return     */    public static String streamToString(InputStream is) {        try {            ByteArrayOutputStream baos = new ByteArrayOutputStream();            byte[] buffer = new byte[1024];            int len = 0;            while ((len = is.read(buffer)) != -1) {                baos.write(buffer, 0, len);            }            baos.close();            is.close();            byte[] byteArray = baos.toByteArray();            return new String(byteArray);        } catch (Exception e) {            Log.v(Common.MSG_ZJAVA, e.toString());            return null;        }    }        class HttpRequestGetRunnable implements Runnable    {    private String baseUrl;    private HashMap<String, String> paramsMap;    private ResultCallback callback;    private Handler handler;        public HttpRequestGetRunnable(String baseUrl,HashMap<String, String> paramsMap,ResultCallback callback)    {    this.baseUrl = baseUrl;    this.paramsMap = paramsMap;    this.callback = callback;    handler = new Handler(Looper.getMainLooper());    }    @Overridepublic void run() {try{StringBuilder tempParams = new StringBuilder();            int pos = 0;            for (String key : paramsMap.keySet()) {                if (pos > 0) {                    tempParams.append("&");                }                tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key),"utf-8")));                pos++;            }            String requestUrl = baseUrl + tempParams.toString();            // 新建一个URL对象            URL url = new URL(requestUrl);                        //设置https            SSLContext sc = SSLContext.getInstance("TLS");            sc.init(null, new TrustManager[]{new MyTrustManager()},new SecureRandom());            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());            HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());                        // 打开一个HttpURLConnection连接            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();            // 设置连接主机超时时间            urlConn.setConnectTimeout(5 * 1000);            //设置从主机读取数据超时            urlConn.setReadTimeout(5 * 1000);            // 设置是否使用缓存  默认是true            urlConn.setUseCaches(true);            // 设置为Post请求            urlConn.setRequestMethod("GET");            //urlConn设置请求头信息            //设置请求中的媒体类型信息。            //urlConn.setRequestProperty("Content-Type", "application/json");            //设置客户端与服务连接类型            urlConn.addRequestProperty("Connection", "Keep-Alive");            // 开始连接            urlConn.connect();            // 判断请求是否成功            if (urlConn.getResponseCode() == 200) {                // 获取返回的数据                final String result = streamToString(urlConn.getInputStream());                handler.post(new Runnable() {@Overridepublic void run() {callback.onResponse(result);}});                                            } else {            handler.post(new Runnable() {@Overridepublic void run() {callback.onError("Get方式请求失败");}});                        }            // 关闭连接            urlConn.disconnect();}catch(final Exception e){handler.post(new Runnable() {@Overridepublic void run() {callback.onError(e.toString());}});}}        }        class HttpRequestPostRunnable implements Runnable    {    private String baseUrl;    private HashMap<String, String> paramsMap;    private ResultCallback callback;    private Handler handler;        public HttpRequestPostRunnable(String baseUrl,HashMap<String, String> paramsMap,ResultCallback callback)    {    this.baseUrl = baseUrl;    this.paramsMap = paramsMap;    this.callback = callback;    handler = new Handler(Looper.getMainLooper());    }    @Overridepublic void run() {try {            //合成参数            StringBuilder tempParams = new StringBuilder();            int pos = 0;            for (String key : paramsMap.keySet()) {                if (pos > 0) {                    tempParams.append("&");                }                tempParams.append(String.format("%s=%s", key,  URLEncoder.encode(paramsMap.get(key),"utf-8")));                pos++;            }            String params =tempParams.toString();            // 请求的参数转换为byte数组            byte[] postData = params.getBytes();            // 新建一个URL对象            URL url = new URL(baseUrl);                        //设置https            SSLContext sc = SSLContext.getInstance("TLS");            sc.init(null, new TrustManager[]{new MyTrustManager()},new SecureRandom());            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());            HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());                        // 打开一个HttpURLConnection连接            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();            // 设置连接超时时间            urlConn.setConnectTimeout(5 * 1000);            //设置从主机读取数据超时            urlConn.setReadTimeout(5 * 1000);            // Post请求必须设置允许输出 默认false            urlConn.setDoOutput(true);            //设置请求允许输入 默认是true            urlConn.setDoInput(true);            // Post请求不能使用缓存            urlConn.setUseCaches(false);            // 设置为Post请求            urlConn.setRequestMethod("POST");            //设置本次连接是否自动处理重定向            urlConn.setInstanceFollowRedirects(true);            // 配置请求Content-Type            //urlConn.setRequestProperty("Content-Type", "application/json");            // 开始连接            urlConn.connect();            // 发送请求参数            DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());            dos.write(postData);            dos.flush();            dos.close();            // 判断请求是否成功            if (urlConn.getResponseCode() == 200) {                // 获取返回的数据                final String result = streamToString(urlConn.getInputStream());                handler.post(new Runnable() {@Overridepublic void run() {callback.onResponse(result);}});            } else {            handler.post(new Runnable() {@Overridepublic void run() {callback.onError("Post方式请求失败");}});            }            // 关闭连接            urlConn.disconnect();        } catch (final Exception e) {            Log.v(Common.MSG_ZJAVA, e.toString());            handler.post(new Runnable() {@Overridepublic void run() {callback.onError(e.toString());}});        }}        }      private class MyHostnameVerifier implements HostnameVerifier{          @Override          public boolean verify(String hostname, SSLSession session)         {              return true;          }}    private class MyTrustManager implements X509TrustManager{          @Override          public X509Certificate[] getAcceptedIssuers() {              return null;          }@Overridepublic void checkClientTrusted(X509Certificate[] arg0,String arg1) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] arg0,String arg1) throws CertificateException {}}public static abstract class ResultCallback    {        public abstract void onError(String e);        public abstract void onResponse(String response);    }}


调用:

    HttpUrlConn.requestPost("https://yourdomain.com", new HashMap<String, String>(), new HttpUrlConn.ResultCallback() {@Overridepublic void onResponse(String response) {// TODO Auto-generated method stubLog.v(Common.MSG_ZJAVA, "Post方式请求成功,result--->" + response);//Toast.makeText(context, "hello world!", Toast.LENGTH_LONG);}@Overridepublic void onError(String e) {// TODO Auto-generated method stubLog.v(Common.MSG_ZJAVA, e);}});



2、OkHttp基础用法

<1>下载okhttp和他所依赖的okio的jar包,放到libs里面

<2>get和post请求代码如下:


package zjava.data.request;import java.io.IOException;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import zjava.sysutil.Common;import android.util.Log;import com.squareup.okhttp.Call;import com.squareup.okhttp.Callback;import com.squareup.okhttp.FormEncodingBuilder;import com.squareup.okhttp.OkHttpClient;import com.squareup.okhttp.Request;import com.squareup.okhttp.RequestBody;import com.squareup.okhttp.Response;public class OkHttpConn {public static void requestGet(String url){//创建okHttpClient对象OkHttpClient mOkHttpClient = new OkHttpClient();//创建一个Requestfinal Request request = new Request.Builder()        .url(url)        .build();//new callCall call = mOkHttpClient.newCall(request); //请求加入调度call.enqueue(new Callback()        {@Overridepublic void onFailure(Request request, IOException exception) {Log.v(Common.MSG_ZJAVA, "失败");}@Overridepublic void onResponse(Response response) throws IOException {Log.v(Common.MSG_ZJAVA, response.body().string());}        }); }public static void requestPost(String url,HashMap<String, String> params){//创建OkHttpClient对象OkHttpClient mOkHttpClient = new OkHttpClient();//通过FormEncodingBuilder对象添加多个请求参数键值对FormEncodingBuilder builder = new FormEncodingBuilder();Iterator iterator = params.entrySet().iterator();while(iterator.hasNext()){Map.Entry<String,String> entry = (Map.Entry) iterator.next();builder.add(entry.getKey(), entry.getValue());}//通过FormEncodingBuilder对象构造Post请求体RequestBody body = builder.build();//通过请求地址和请求体构造Post请求对象RequestRequest request = new Request.Builder().url(url).post(body).build();// 下面一样Call call = mOkHttpClient.newCall(request); //请求加入调度call.enqueue(new Callback()        {@Overridepublic void onFailure(Request request, IOException exception) {Log.v(Common.MSG_ZJAVA, "失败");}@Overridepublic void onResponse(Response response) throws IOException {Log.v(Common.MSG_ZJAVA, response.body().string());}        }); }}


调用方法很简单这里就不说了。


3、okhttp的再次封装

参见大神写的,我直接拿来用了:

教程:

http://blog.csdn.net/lmj623565791/article/details/47911083

代码:

https://github.com/hongyangAndroid/okhttputils

注意:

<1>要使用这个代码需要添加2个类,一个是主要的类OkHttpClientManager,另一个是里面用到的ImageUtils,其他的可以不管。

<2>由于这个类用到了google的json解析工具,所以要导入Gson类库。

<3>这样使用:

get->

    OkHttpClientManager.getAsyn("http://yourdomain.com/push_url",new OkHttpClientManager.ResultCallback<String>()     {@Overridepublic void onError(Request request, Exception e) {}@Overridepublic void onResponse(String response) {// TODO Auto-generated method stubLog.v(Common.MSG_ZJAVA, response);}});

post->

    HashMap<String, String> params = new HashMap<String, String>();    params.put("m", "p");    params.put("k", "myvalue");        OkHttpClientManager.postAsyn("http://yourdomain.com/push_url", new OkHttpClientManager.ResultCallback<String>() {@Overridepublic void onError(Request request, Exception e) {// TODO Auto-generated method stub}@Overridepublic void onResponse(String response) {// TODO Auto-generated method stubLog.v(Common.MSG_ZJAVA, response);}}, params);





0 0