首先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.youkuaiyun.com/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);