android网络访问之HttpURLConnection vs OkHttp

    xiaoxiao2021-03-25  94

    首先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; } @Override public 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; } @Override public 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()); } @Override public 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() { @Override public void run() { callback.onResponse(result); } }); } else { handler.post(new Runnable() { @Override public void run() { callback.onError("Get方式请求失败"); } }); } // 关闭连接 urlConn.disconnect(); }catch(final Exception e) { handler.post(new Runnable() { @Override public 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()); } @Override public 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() { @Override public void run() { callback.onResponse(result); } }); } else { handler.post(new Runnable() { @Override public void run() { callback.onError("Post方式请求失败"); } }); } // 关闭连接 urlConn.disconnect(); } catch (final Exception e) { Log.v(Common.MSG_ZJAVA, e.toString()); handler.post(new Runnable() { @Override public 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; } @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } @Override public 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() { @Override public void onResponse(String response) { // TODO Auto-generated method stub Log.v(Common.MSG_ZJAVA, "Post方式请求成功,result--->" + response); //Toast.makeText(context, "hello world!", Toast.LENGTH_LONG); } @Override public void onError(String e) { // TODO Auto-generated method stub Log.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(); //创建一个Request final Request request = new Request.Builder() .url(url) .build(); //new call Call call = mOkHttpClient.newCall(request); //请求加入调度 call.enqueue(new Callback() { @Override public void onFailure(Request request, IOException exception) { Log.v(Common.MSG_ZJAVA, "失败"); } @Override public 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请求对象Request Request request = new Request.Builder().url(url).post(body).build(); // 下面一样 Call call = mOkHttpClient.newCall(request); //请求加入调度 call.enqueue(new Callback() { @Override public void onFailure(Request request, IOException exception) { Log.v(Common.MSG_ZJAVA, "失败"); } @Override public 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>() { @Override public void onError(Request request, Exception e) { } @Override public void onResponse(String response) { // TODO Auto-generated method stub Log.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>() { @Override public void onError(Request request, Exception e) { // TODO Auto-generated method stub } @Override public void onResponse(String response) { // TODO Auto-generated method stub Log.v(Common.MSG_ZJAVA, response); } }, params);

    转载请注明原文地址: https://ju.6miu.com/read-22718.html

    最新回复(0)