package com.giant.zzidc.util;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
public class HttpClientUtils {
private static Logger logger = Logger.getLogger(HttpClientUtils.class);
/** 连接超时时间(3分钟) */
private static final int connectTimeout = 1000 * 60 * 3;
/** 读取数据超时时间(30分钟) */
private static final int socketTimeout = 1000 * 60 * 30;
/**
* HTTP GET请求(HttpClient实现)
*
* @param url
* 请求地址(如有参数,请拼接在地址后面)
* @param charset
* 字符编码集(可为空)
* @return 响应结果(可能为null)
* @throws Exception
* 错误原因
*/
public static String doGet(String url, String charset) throws Exception {
if (url == null || "".equals(url = url.trim()))
throw new Exception("请求地址不能为空!");
if (charset != null && !Charset.isSupported(charset))
throw new Exception("不支持的字符编码集:" + charset);
long startTime = 0;
CloseableHttpClient client = null;
CloseableHttpResponse response = null;
try {
client = HttpClients.createDefault();/* 创建HttpClinet实例 */
logger.info("地址:" + url);
HttpGet get = new HttpGet(url);/* 创建Get方法实例 */
get.setConfig(RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build());/* 设置请求和传输超时时间 */
startTime = System.nanoTime();
response = client.execute(get);
} catch (Exception e) {
logger.error("通讯异常:" + e.toString());
logger.info("用时:" + (System.nanoTime() - startTime) / 1000000L + "毫秒");
closeClient(client, response);
throw new Exception("通讯异常:" + e.getMessage());
}
StringBuffer result = new StringBuffer();
try {
int code = response.getStatusLine().getStatusCode();
logger.info("状态码:" + code);
HttpEntity entity = response.getEntity();
if (entity != null) {
long len = entity.getContentLength();
if (len != -1 && len < 2048) {/* 当返回值长度较小的时候,使用工具类 */
if (charset == null) {
result.append(EntityUtils.toString(entity));
} else {
result.append(EntityUtils.toString(entity, charset));
}
} else {/* 否则使用IO流来读取 */
BufferedReader reader;
if (charset == null) {
reader = new BufferedReader(new InputStreamReader(entity.getContent()));
} else {
reader = new BufferedReader(new InputStreamReader(entity.getContent(), charset));
}
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
reader.close();
}
logger.info("返回:" + result.toString());
logger.info("用时:" + (System.nanoTime() - startTime) / 1000000L + "毫秒");
}
} catch (Exception e) {
logger.error("处理响应时出现异常:" + e.toString());
logger.info("用时:" + (System.nanoTime() - startTime) / 1000000L + "毫秒");
throw new Exception("处理响应时出现异常:" + e.getMessage());
} finally {
closeClient(client, response);
}
return result.length() == 0 ? null : result.toString();
}
/** 关闭HttpClient */
private static void closeClient(CloseableHttpClient client, CloseableHttpResponse response) {
if (response != null) {
try {
response.close();
} catch (Exception e) {
logger.error("关闭HttpResponse出错:" + e.toString());
}
}
if (client != null) {
try {
client.close();
} catch (Exception e) {
logger.error("关闭HttpClient出错:" + e.toString());
}
}
}
@SuppressWarnings("unused")
public static String getEnt(Object parameter, String charset) throws Exception{
if (charset != null && !Charset.isSupported(charset))
throw new Exception("不支持的字符编码集:" + charset);
HttpEntity entity = null;
if (parameter != null) {
try {
entity = parameterHandle(parameter, charset);/* 处理参数 */
} catch (Exception e) {
throw new Exception("参数错误:" + e.getMessage());
}
}
long startTime = 0;
CloseableHttpClient client = null;
CloseableHttpResponse response = null;
client = HttpClients.createDefault();/* 创建HttpClinet实例 */
if (entity != null) {
logger.info("参数:" + EntityUtils.toString(entity));
}
return EntityUtils.toString(entity);
}
/**
* HTTP POST请求(HttpClient实现)
*
* @param url
* 请求地址
* @param parameter
* 参数(可为空;允许的类型为:String, List<NameValuePair>, Map<String, Object>)
* @param charset
* 字符编码集(可为空)
* @return 响应结果(可能为null)
* @throws Exception
* 错误原因
*/
public static String doPost(String url, Object parameter, String charset) throws Exception {
if (url == null || "".equals(url = url.trim()))
throw new Exception("请求地址不能为空!");
if (charset != null && !Charset.isSupported(charset))
throw new Exception("不支持的字符编码集:" + charset);
HttpEntity entity = null;
if (parameter != null) {
try {
entity = parameterHandle(parameter, charset);/* 处理参数 */
} catch (Exception e) {
throw new Exception("参数错误:" + e.getMessage());
}
}
long startTime = 0;
CloseableHttpClient client = null;
CloseableHttpResponse response = null;
try {
client = HttpClients.createDefault();/* 创建HttpClinet实例 */
logger.info("地址:" + url);
HttpPost post = new HttpPost(url);/* 创建Post方法实例 */
post.setConfig(RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build());/* 设置请求和传输超时时间 */
if (entity != null) {
logger.info("参数:" + EntityUtils.toString(entity));
post.setEntity(entity);/* 设置参数 */
}
startTime = System.nanoTime();
response = client.execute(post);
} catch (Exception e) {
logger.error("通讯异常:" + e.toString());
logger.info("用时:" + (System.nanoTime() - startTime) / 1000000L + "毫秒");
closeClient(client, response);
throw new Exception("通讯异常:" + e.getMessage());
}
StringBuffer result = new StringBuffer();
try {
int code = response.getStatusLine().getStatusCode();
logger.info("状态码:" + code);
entity = response.getEntity();
if (entity != null) {
long len = entity.getContentLength();
if (len != -1 && len < 2048) {/* 当返回值长度较小的时候,使用工具类 */
if (charset == null) {
result.append(EntityUtils.toString(entity));
} else {
result.append(EntityUtils.toString(entity, charset));
}
} else {/* 否则使用IO流来读取 */
BufferedReader reader;
if (charset == null) {
reader = new BufferedReader(new InputStreamReader(entity.getContent()));
} else {
reader = new BufferedReader(new InputStreamReader(entity.getContent(), charset));
}
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
reader.close();
}
logger.info("返回:" + result.toString());
logger.info("用时:" + (System.nanoTime() - startTime) / 1000000L + "毫秒");
}
} catch (Exception e) {
logger.error("处理响应时出现异常:" + e.toString());
logger.info("用时:" + (System.nanoTime() - startTime) / 1000000L + "毫秒");
throw new Exception("处理响应时出现异常:" + e.getMessage());
} finally {
closeClient(client, response);
}
return result.length() == 0 ? null : result.toString();
}
/**
* 参数处理
*
* @param parameter
* 参数(允许的类型为:String, List<NameValuePair>, Map<String, Object>)
* @param charset
* 字符编码集(可为空)
* @return org.apache.http.HttpEntity
* @throws Exception
* 错误原因:不支持的字符编码集;不支持的参数类型
*/
@SuppressWarnings("unchecked")
private static HttpEntity parameterHandle(Object parameter, String charset) throws Exception {
if (parameter == null)
return null;
if (charset != null && !Charset.isSupported(charset))
throw new Exception("不支持的字符编码集:" + charset);
if (parameter instanceof String) {
return charset == null ? new StringEntity((String) parameter) : new StringEntity((String) parameter, charset);
}
if (parameter instanceof JSONObject) {
StringEntity strEntity = charset == null ? new StringEntity(parameter.toString()) : new StringEntity(parameter.toString(),
charset);
strEntity.setContentEncoding(charset);
strEntity.setContentType("application/json");
return strEntity;
}
List list = null;
if (parameter instanceof List) {
List> temp = (List>) parameter;
if (!temp.isEmpty()) {
Object o = temp.get(0);
if (o instanceof NameValuePair)
list = (List) parameter;
else
throw new Exception("不支持的参数类型:List<" + o.getClass().getCanonicalName() + ">");
}
} else if (parameter instanceof Map) {
Map map = (Map) parameter;
list = new ArrayList();
for (Entry en : map.entrySet()) {
list.add(new BasicNameValuePair(en.getKey(), String.valueOf(en.getValue())));
}
} else {
throw new Exception("不支持的参数类型:" + parameter.getClass().getCanonicalName());
}
if (list == null || list.isEmpty())
return null;
return charset == null ? new UrlEncodedFormEntity(list) : new UrlEncodedFormEntity(list, charset);
}
/**
* 接口调用(返回字符串)(POST)
*
* @param url
* 接口地址
* @param parameter
* 参数(可为空;允许的类型为:String, List<NameValuePair>, Map<String, Object>)
* @return 接口返回值(字符串对象)
* @throws Exception
* 失败原因
*/
public static String invoke(String url, Object parameter) throws Exception {
if (url == null || "".equals(url = url.trim()))
throw new Exception("请求地址为空!");
String result = doPost(url, parameter, "UTF-8");
if (result == null || "".equals(result = result.trim()))
throw new Exception("接口返回空值!");
return result;
}
/**
* 接口调用(返回JSON对象)(POST)
*
* @param url
* 接口地址
* @param parameter
* 参数(可为空;允许的类型为:String, List<NameValuePair>, Map<String, Object>)
* @return 接口返回值(JSON对象)
* @throws Exception
* 失败原因
*/
public static JSONObject invokeJSON(String url, Object parameter) throws Exception {
String result = invoke(url, parameter);
try {
return JSONObject.fromObject(result);
} catch (Exception e) {
throw new Exception("返回值不是JSON字符串:" + result);
}
}
public static JSONObject invokeResult(String url, Object parameter){
try {
String result = invoke(url, parameter);
return JSONObject.fromObject(result);
} catch (Exception e) {
JSONObject json = new JSONObject();
json.put("code", -10001);
json.put("message", "调用接口出现异常!");
json.put("dcode", -10001);
json.put("dmessage", "调用接口出现异常!");
return json;
}
}
/**
* 接口调用(返回布尔值)(POST)
*
* @param url
* 接口地址
* @param parameter
* 参数(可为空;允许的类型为:String, List<NameValuePair>, Map<String, Object>)
* @return true:成功
* @throws Exception
* 失败原因
*/
public static boolean invokeBoolean(String url, Object parameter) throws Exception {
JSONObject json = invokeJSON(url, parameter);
if (json.getInt("state") == 1) {
return true;
} else {
throw new Exception(json.getString("info"));
}
}
/**
* 接口调用(返回Map<String, Object>)(POST)
*
* @param url
* 接口地址
* @param parameter
* 参数(可为空;允许的类型为:String, List<NameValuePair>, Map<String, Object>)
* @return 接口返回值(Map<String, Object>对象)
* @throws Exception
* 失败原因
*/
@SuppressWarnings("unchecked")
public static Map invokeMap(String url, Object parameter) throws Exception {
JSONObject json = invokeJSON(url, parameter);
if (json.getInt("state") == 1) {
return (Map) JSONObject.toBean(json, Map.class);
} else {
throw new Exception(json.getString("info"));
}
}
}