HttpUtils 封装类

作为一个web开发人员,对Http 请求,并不陌生。有时候,我们请求的时候,需要使用代码实现,一般情况,我们使用Apache Jakarta Common 下的子项目.的HttpClient.

可是我发现,在开发过成,很多情况,我们使用的功能,并不需要,想象中的需要HttpClient 的很多特性。而且,需要引用jar 。这边我们使用Java jdk自带的HttpsURLConnection.

而且,这个可以迁移到android项目封装成一个HttpUtils 方法。代码如下:

package com.xuanyuan.utils.http;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * HttpUtils帮助类
 * User: PunkLin林克澎
 * Email: [email protected]
 * Date: 2017-04-04
 */
public class HttpUtils {

	private static Charset charset=Charset.defaultCharset();
	private static final String TAG = "HttpUtils";
	//链接超时
	private static final int mReadTimeOut = 1000 * 10; // 10秒
	//链接超时
	private static final int mConnectTimeOut = 1000 * 5; // 5秒
	private static final String CHAR_SET = charset.displayName();

	private static final int mRetry = 2; // 默认尝试访问次数

	/**
	 * 处理访问字符串处理
	 * @param params
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private static String buildParams(Map<String,? extends Object> params) throws UnsupportedEncodingException{
		if(params ==null || params.isEmpty()){
			return null;
		}
		StringBuilder builder = new StringBuilder();
		for (Map.Entry<String, ? extends Object> entry : params.entrySet()) {
			if (entry.getKey() != null && entry.getValue() != null)
				builder.append(entry.getKey().trim()).append("=")
						.append(URLEncoder.encode(entry.getValue().toString(), CHAR_SET)).append("&");
		}
		if(builder.charAt(builder.length()-1)==‘&‘){
			builder.deleteCharAt(builder.length()-1);
		}
		return builder.toString();
	}

	/**
	 * 无参数的Get访问
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public static String get(String url) throws Exception {
		return get(url, null);
	}

	/**
	 * 有参数的Get 访问
	 * @param url
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static String get(String url, Map<String, ? extends Object> params) throws Exception {
		return get(url, params, null);
	}

	/**
	 * 含有报文头的Get请求
	 * @param url
	 * @param params
	 * @param headers
	 * @return
	 * @throws Exception
	 */
	public static String get(String url, Map<String, ? extends Object> params, Map<String, String> headers) throws Exception {
		if (url == null || url.trim().length() == 0) {
			throw new Exception(TAG + ": url is null or empty!");
		}

		if (params != null && params.size() > 0) {
			if (!url.contains("?")) {
				url += "?";
			}
			if (url.charAt(url.length() - 1) != ‘?‘) {
				url += "&";
			}
			url += buildParams(params);
		}

		return tryToGet(url, headers);
	}

	private static String tryToGet(String url,Map<String,String> headers) throws Exception{
		int tryTime = 0;
		Exception ex = null;
		while (tryTime < mRetry) {
			try {
				return doGet(url, headers);
			} catch (Exception e) {
				if (e != null)
					ex = e;
				tryTime++;
			}
		}
		if (ex != null)
			throw ex;
		else
			throw new Exception("未知网络错误 ");
	}

	/**
	 * Get 请求实现方法 核心
	 * @param strUrl
	 * @param headers
	 * @return
	 * @throws Exception
	 */
	private static String doGet(String strUrl, Map<String, String> headers) throws Exception {
		HttpURLConnection connection = null;
		InputStream stream = null;
		try {

			connection = getConnection(strUrl);
			configConnection(connection);
			if (headers != null && headers.size() > 0) {
				for (Map.Entry<String, String> entry : headers.entrySet()) {
					connection.setRequestProperty(entry.getKey(), entry.getValue());
				}
			}

			connection.setInstanceFollowRedirects(true);
			connection.connect();

			stream = connection.getInputStream();
			ByteArrayOutputStream obs = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			for (int len = 0; (len = stream.read(buffer)) > 0;) {
				obs.write(buffer, 0, len);
			}
			obs.flush();
			obs.close();
			stream.close();

			return new String(obs.toByteArray());
		} finally {
			if (connection != null) {
				connection.disconnect();
			}
			if (stream != null) {
				stream.close();
			}
		}
	}

	/**
	 * Post 请求,无参数的请求
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public static String post(String url) throws Exception {
		return post(url, null);
	}

	/**
	 * Post 请求,带参数的请求。
	 * @param url
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static String post(String url, Map<String, ? extends Object> params) throws Exception {
		return post(url, params, null);
	}

	/**
	 * Post 请求,带参数的请求,请求报文的
	 * @param url
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static String post(String url, Map<String, ? extends Object> params, Map<String, String> headers)
			throws Exception {
		if (url == null || url.trim().length() == 0) {
			throw new Exception(TAG + ":url is null or empty!");
		}

		if (params != null && params.size() > 0) {
			return tryToPost(url, buildParams(params), headers);
		} else {
			return tryToPost(url, null, headers);
		}
	}

	public static String post(String url, String content, Map<String, String> headers) throws Exception {
		return tryToPost(url, content, headers);
	}

	private static String tryToPost(String url, String postContent, Map<String, String> headers) throws Exception {
		int tryTime = 0;
		Exception ex = null;
		while (tryTime < mRetry) {
			try {
				return doPost(url, postContent, headers);
			} catch (Exception e) {
				if (e != null)
					ex = e;
				tryTime++;
			}
		}
		if (ex != null)
			throw ex;
		else
			throw new Exception("未知网络错误 ");
	}

	private static String doPost(String strUrl, String postContent, Map<String, String> headers) throws Exception {
		HttpURLConnection connection = null;
		InputStream stream = null;
		try {
			connection = getConnection(strUrl);
			configConnection(connection);
			if (headers != null && headers.size() > 0) {
				for (Map.Entry<String, String> entry : headers.entrySet()) {
					connection.setRequestProperty(entry.getKey(), entry.getValue());
				}
			}
			connection.setRequestMethod("POST");
			connection.setDoOutput(true);

			if (null != postContent && !"".equals(postContent)) {
				DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
				dos.write(postContent.getBytes(CHAR_SET));
				dos.flush();
				dos.close();
			}
			stream = connection.getInputStream();
			ByteArrayOutputStream obs = new ByteArrayOutputStream();

			byte[] buffer = new byte[1024];
			for (int len = 0; (len = stream.read(buffer)) > 0;) {
				obs.write(buffer, 0, len);
			}
			obs.flush();
			obs.close();
			return new String(obs.toByteArray());
		} finally {
			if (connection != null) {
				connection.disconnect();
			}
			if (stream != null) {
				stream.close();
			}
		}
	}

	private static void configConnection(HttpURLConnection connection){
		if(connection==null){
			return;
		}

		connection.setReadTimeout(mReadTimeOut);
		connection.setConnectTimeout(mConnectTimeOut);
		connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		connection.setRequestProperty("User-Agent",
				"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
	}

	/**
	 * 根据输入的请求地址判断使用https 还是使用http 获取不同的HttpURLConnection.
	 * @param strUrl
	 * @return
	 * @throws Exception
	 */
	private static HttpURLConnection getConnection(String strUrl) throws Exception {
		if(strUrl == null){
			return null;
		}
		if(strUrl.toLowerCase().startsWith("https")){
			return getHttpsConnection(strUrl);
		}else{
			return getHttpConnection(strUrl);
		}
	}

	//获取HTTP
	private static HttpURLConnection getHttpConnection(String urlStr) throws Exception {
		URL url =new URL(urlStr);
		HttpURLConnection conn=(HttpURLConnection) url.openConnection();
		return conn;
	}

	private static HttpURLConnection getHttpsConnection(String urlStr) throws Exception {
		URL url =new URL(urlStr);
		HttpsURLConnection conn=(HttpsURLConnection) url.openConnection();
		conn.setHostnameVerifier(hnv);
		SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
		if(sslContext != null){
			TrustManager[] tm={xtm};
			sslContext.init(null, tm, null);
			SSLSocketFactory ssf =sslContext.getSocketFactory();
			conn.setSSLSocketFactory(ssf);
		}

		return conn;
	}

	private static X509TrustManager xtm = new X509TrustManager() {

		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	};

	/**
	 * 用于主机名验证的基接口
	 */
	private static HostnameVerifier hnv = new HostnameVerifier() {
		 //验证主机名和服务器验证方案的匹配是可接受的。 可以接受返回true
		 public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	};
}

这样,少了很多jar的引用。并且功能实现了 Https.

时间: 2024-11-10 07:27:40

HttpUtils 封装类的相关文章

Android学习之xUtils --- HttpUtils模块

HttpUtils是解决日常工作过程中繁杂的上传下载文件以及各种Get和post请求的必备工具类. 通过这个类, 非常方便的进行网络访问下载等操作,不必再再写那么冗长的代码. HttpGet请求 和 HttpPost请求 Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE. 其中最常用的就是GET,POST 根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的. 根据HTTP规范,POST表示可能修改变服务器上的资源的请求 GET请求

Windows下libevent C++封装类实现

题记 windows平台下对于服务器高并发的网络模型选型中,使用libevent是个不错的选择. 本文的背景基于:国内博客对于libevent大多介绍linux实现,大多是c语言的实现,Windows平台下C++相对较少或者较旧. 本文针对libevent从服务端.客户端两个角度实现了封装类,真正做到,我们在使用封装类时候,只需要关注业务逻辑的处理,不需要关注socket的通信的细节. 1. Libevent介绍 [维基百科]libevent是一个异步事件处理软件函式库,以BSD许可证发布.li

php数据库操作封装类

<?php /** * Desc: php操作mysql的封装类 * Author zhifeng * Date: 2015/04/15 * 连接模式:PDO */ class MMysql { protected static $_dbh = null; //静态属性,所有数据库实例共用,避免重复连接数据库 protected $_dbType = 'mysql'; protected $_pconnect = true; //是否使用长连接 protected $_host = 'local

【Cocos2d-x Lua】操作数据库封装类

Lua中操作数据库封装类 使用示例 lua代码: require("DB") -- 保存一个字符串(数据库中存储的数据都是以字符串的形式保存的) DB:getInstance():setString("level",level) -- 根据key(isOpenMusic)返回一个数字,第二个参数为默认返回值 local result = DB:getInstance():getNumber("isOpenMusic",1) -- 根据key(is

HttpUtils.java 网络下载工具类

package Http; import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL; /** * 网络下载工具类 * 功能:下载字节数组,下载文本数据 * 下载数字数组(文本 图片 mp3) * 下载文本数据 * Created by lxj-pc on 2017/

EF通用数据层封装类(支持读写分离,一主多从)

浅谈orm 记得四年前在学校第一次接触到 Ling to Sql,那时候瞬间发现不用手写sql语句是多么的方便,后面慢慢的接触了许多orm框架,像 EF,Dapper,Hibernate,ServiceStack.OrmLite 等.当然每种orm都有各自的优势,也有不足的地方.园子里也有很多大神开源了他们写的orm,如SqlSugar,Chloe.ORM,CYQ.Data 等.先不说这些开源的orm使用度怎么样,我觉得起码从开源的精神上就很可嘉了,我也曾下载过这几位大神的源码进行学习. 所有o

学生管理系统----学生封装类

Student.java: /** * @Title:Student.java * @Package:com.you.student.system.model * @Description:学生信息封装类 * @author:Youhaidong(游海东) * @date:2014-6-16 下午11:00:22 * @version V1.0 */ package com.you.student.system.model; import java.io.Serializable; import

封装类(Merry May Day to all you who are burried in work ~)---2017-05-01

1.为什么要使用封装类? (1) 可以多个地方调用,避免代码的冗余 (2)面向对象三大特点之一,安全性高 2.代码及注意点? <?php class DB //文件名为:DB.class.php 类名必须与文件名前面相同 { public $host = "localhost"; public $uid = "root"; public $pwd = "123"; public $dbname ="friends"; /

httpUtils网络请求

String path = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; HttpUtils httpUtils = new HttpUtils(); // 参数一:请求方式 // 参数二:url // 参数三:RequestParams params, 请求参数 // 参数四:RequestCallBack<T> callBack 回调通知接口 // RequestParams params=new RequestParams(); /