Android网络请求框架非常多,github一搜就是一堆.我的博客就不讲这些,我就讲讲原生已经够用了.
HttpURLConnection是Android提供的一个网络请求库,个人认为,还是蛮好用的.
HttpsURLConnection是本身就继承自HttpURLConnection的类
首先是忽略证书这一块.有些请求涉及到请求证书.加载证书似乎很麻烦.(不麻烦,我不想加载)
首先需要初始化,一般我喜欢封装一个工具类,然后在静态代码块中,进行初始化
static {
try {
ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager(null)}, new SecureRandom());
ctx.getClientSessionContext().setSessionTimeout(15);
ctx.getClientSessionContext().setSessionCacheSize(1000);
socketFactory = ctx.getSocketFactory();
} catch (Exception ignored) {
}
verifier = new HostnameVerifier();
}
其中的new TrustManager[]{new WebUtils.DefaultTrustManager(null)}.只是继承了X509TrustManager进行使用
private static class DefaultTrustManager implements X509TrustManager {
private DefaultTrustManager(Object o) {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
}
HostnameVerifier中我对忽略规则做了处理,特殊请求的url,证书还是需要的
Pattern.compile("([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)");
如果匹配上这条正则.则需要ssl协议
关键点在于获取Connection的时候做的处理
// new URL即可,请求方法,post还是get.Content-type,一般都是utf-8
private static HttpURLConnection getConnection(URL url, String method, String ctype) throws IOException {
HttpURLConnection conn = null;
if ("https".equals(url.getProtocol())) {
// ssl证书管理在这里
HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();
connHttps.setSSLSocketFactory(socketFactory);
connHttps.setHostnameVerifier(verifier);
conn = connHttps;
} else {
conn = (HttpURLConnection) url.openConnection();
}
conn.setRequestMethod(method);
conn.setAllowUserInteraction(true);
conn.setInstanceFollowRedirects(true);
if (method.equalsIgnoreCase("post")) {
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
}
// cookie也可以在这里设置
// conn.setRequestProperty("Set-Cookie", "");
conn.setRequestProperty("User-Agent","");
conn.setRequestProperty("Content-Type", "");
return conn;
}
使用也是非常的简单
public static byte[] doGet(String url, Map params) {
HttpURLConnection conn = null;
String responseBody = null;
byte[] bytes = new byte[0];
try {
// 这里我写了一个方法.把get请求的参数作为拼接
conn = getConnection(new URL(getQueryUrl(url, params)), "GET", "*/*;charset=utf-8");
conn.setReadTimeout(0);
conn.setConnectTimeout(0);
bytes = readInputStream(conn.getInputStream());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return bytes;
}
附上完整工具类
public class WebUtils {
private static final String DEFAULT_CHARSET = "UTF-8";
private static final String METHOD_POST = "POST";
private static final String METHOD_GET = "GET";
private static SSLContext ctx = null;
private static HostnameVerifier verifier = null;
private static SSLSocketFactory socketFactory = null;
private WebUtils() {
}
public static String doPostStringResponse(String url, String json) {
Log.d("WebUtils", url);
HttpURLConnection conn = null;
String responseBody = null;
try {
conn = getConnection(new URL(url), "POST", "application/json;charset=utf-8");
conn.setReadTimeout(0);
conn.setConnectTimeout(0);
// post发送json数据
if (!TextUtils.isEmpty(json)) {
byte[] bytes = json.getBytes();
conn.setRequestProperty("Content-Length", bytes.length + "");
OutputStream outputStream = conn.getOutputStream();
outputStream.write(bytes);
outputStream.flush();
outputStream.close();
}
byte[] bytes = readInputStream(conn.getInputStream());
responseBody = new String(bytes, "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return responseBody;
}
public static byte[] doGet(String url) {
return doGet(url, null);
}
public static byte[] doGet(String url, Map params) {
HttpURLConnection conn = null;
String responseBody = null;
byte[] bytes = new byte[0];
try {
conn = getConnection(new URL(getQueryUrl(url, params)), "GET", "*/*;charset=utf-8");
conn.setReadTimeout(0);
conn.setConnectTimeout(0);
bytes = readInputStream(conn.getInputStream());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return bytes;
}
private static byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
inputStream.close();
return bos.toByteArray();
}
private static HttpURLConnection getConnection(URL url, String method, String ctype) throws IOException {
HttpURLConnection conn = null;
if ("https".equals(url.getProtocol())) {
HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();
connHttps.setSSLSocketFactory(socketFactory);
connHttps.setHostnameVerifier(verifier);
conn = connHttps;
} else {
conn = (HttpURLConnection) url.openConnection();
}
conn.setRequestMethod(method);
conn.setAllowUserInteraction(true);
conn.setInstanceFollowRedirects(true);
// post方法必须加上,get方法是不需要这些,否则会失败
if (method.equalsIgnoreCase("post")) {
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
}
// cookie也可以在这里设置
// conn.setRequestProperty("Set-Cookie", "");
conn.setRequestProperty("User-Agent", Settings.UA);
conn.setRequestProperty("Content-Type", ctype);
return conn;
}
static {
try {
ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[]{new WebUtils.DefaultTrustManager(null)}, new SecureRandom());
ctx.getClientSessionContext().setSessionTimeout(15);
ctx.getClientSessionContext().setSessionCacheSize(1000);
socketFactory = ctx.getSocketFactory();
} catch (Exception ignored) {
}
verifier = new HostnameVerifier();
}
/**
* 拼接get数据
*
* @param url 地址
* @param params get参数
* @return
*/
private static String getQueryUrl(String url, Map params) {
StringBuilder neoUrl = new StringBuilder(url);
if (params != null) {
neoUrl.append("?");
for (Map.Entry stringStringEntry : params.entrySet()) {
neoUrl.append(stringStringEntry.getKey()).append("=").append(stringStringEntry.getValue()).append("&");
}
neoUrl = new StringBuilder(neoUrl.substring(0, neoUrl.length() - 1));
}
return neoUrl.toString();
}
private static class DefaultTrustManager implements X509TrustManager {
private DefaultTrustManager(Object o) {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
}
}
以及HostnameVerifier
public class HostnameVerifier implements javax.net.ssl.HostnameVerifier {
public static final HostnameVerifier INSTANCE = new HostnameVerifier();
private static final int ALT_DNS_NAME = 2;
private static final int ALT_IPA_NAME = 7;
private static final Pattern VERIFY_AS_IP_ADDRESS = Pattern.compile("([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)");
HostnameVerifier() {
}
public boolean verify(String host, SSLSession session) {
try {
Certificate[] certificates = session.getPeerCertificates();
return this.verify(host, (X509Certificate)certificates[0]);
} catch (SSLException var4) {
return false;
}
}
public boolean verify(String host, X509Certificate certificate) {
return verifyAsIpAddress(host)?this.verifyIpAddress(host, certificate):this.verifyHostname(host, certificate);
}
private boolean verifyIpAddress(String ipAddress, X509Certificate certificate) {
List altNames = getSubjectAltNames(certificate, 7);
int i = 0;
for(int size = altNames.size(); i < size; ++i) {
if(ipAddress.equalsIgnoreCase((String)altNames.get(i))) {
return true;
}
}
return false;
}
private boolean verifyHostname(String hostname, X509Certificate certificate) {
hostname = hostname.toLowerCase(Locale.US);
List altNames = getSubjectAltNames(certificate, 2);
Iterator var4 = altNames.iterator();
String altName;
do {
if(!var4.hasNext()) {
return false;
}
altName = (String)var4.next();
} while(!this.verifyHostname(hostname, altName));
return true;
}
public static List allSubjectAltNames(X509Certificate certificate) {
List altIpaNames = getSubjectAltNames(certificate, 7);
List altDnsNames = getSubjectAltNames(certificate, 2);
List result = new ArrayList(altIpaNames.size() + altDnsNames.size());
result.addAll(altIpaNames);
result.addAll(altDnsNames);
return result;
}
private static List getSubjectAltNames(X509Certificate certificate, int type) {
ArrayList result = new ArrayList();
try {
Collection> subjectAltNames = certificate.getSubjectAlternativeNames();
if(subjectAltNames == null) {
return Collections.emptyList();
} else {
Iterator var4 = subjectAltNames.iterator();
while(var4.hasNext()) {
Object subjectAltName = var4.next();
List> entry = (List)subjectAltName;
if(entry != null && entry.size() >= 2) {
Integer altNameType = (Integer)entry.get(0);
if(altNameType != null && altNameType.intValue() == type) {
String altName = (String)entry.get(1);
if(altName != null) {
result.add(altName);
}
}
}
}
return result;
}
} catch (CertificateParsingException var9) {
return Collections.emptyList();
}
}
public boolean verifyHostname(String hostname, String pattern) {
if(hostname != null && hostname.length() != 0 && !hostname.startsWith(".") && !hostname.endsWith("..")) {
if(pattern != null && pattern.length() != 0 && !pattern.startsWith(".") && !pattern.endsWith("..")) {
if(!hostname.endsWith(".")) {
hostname = hostname + '.';
}
if(!pattern.endsWith(".")) {
pattern = pattern + '.';
}
pattern = pattern.toLowerCase(Locale.US);
if(!pattern.contains("*")) {
return hostname.equals(pattern);
} else if(pattern.startsWith("*.") && pattern.indexOf(42, 1) == -1) {
if(hostname.length() < pattern.length()) {
return false;
} else if("*.".equals(pattern)) {
return false;
} else {
String suffix = pattern.substring(1);
if(!hostname.endsWith(suffix)) {
return false;
} else {
int suffixStartIndexInHostname = hostname.length() - suffix.length();
return suffixStartIndexInHostname <= 0 || hostname.lastIndexOf(46, suffixStartIndexInHostname - 1) == -1;
}
}
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
public static boolean verifyAsIpAddress(String host) {
return VERIFY_AS_IP_ADDRESS.matcher(host).matches();
}
}