package com.common.utils;
/*
*-----------------------------------------------------------------
* IBM Confidential
*
* OCO Source Materials
*
* WebSphere Commerce
*
* (C) Copyright IBM Corp. 2011
*
* The source code for this program is not published or otherwise
* divested of its trade secrets, irrespective of what has
* been deposited with the U.S. Copyright Office.
*-----------------------------------------------------------------
*/
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Created on Nov 21, 2010
*
* Http and Https connection utility.
*/
public class HttpConnectionUtil {
public static final String CLASS_NAME = HttpConnectionUtil.class.getName();
/** The send method : POST. */
public static final String SEND_METHOD_POST = "POST";
/** The send method : GET. */
public static final String SEND_METHOD_GET = "GET";
/** The char set : UTF-8. */
public static final String CHARSET_UTF8 = "UTF-8";
/** The char set : GB2312. */
public static final String CHARSET_GB2312 = "GB2312";
/** The char set : GBK. */
public static final String CHARSET_GBK = "GBK";
/** 1 Second is equal to 1,000 millisecond. */
public static final long MILLI_SECOND = 1000;
public static final long DEFAULT_CONNECT_TIMEOUTSECONDS = 1;
public static final long DEFAULT_READ_TIMEOUTSECONDS = 3;
/** HTTP request property : HTTP1.1 JSON. */
public static final String CONTENT_TYPE_APP_JSON = "application/json";
/** HTTP request property : HTTP1.1 FORM. */
public static final String CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";
/** HTTP request property : HTTP1.1 TEXT XML. */
public static final String CONTENT_TYPE_TEXT_XML = "text/xml";
/** HTTP request property : HTTP1.1 APPLICATION XML. */
public static final String CONTENT_TYPE_APP_XML = "application/xml";
private static final Logger LOGGER = LoggerFactory.getLogger(HttpConnectionUtil.class);
/** The separator symbol. */
private static final String SYMBOL_SEPERATOR = "&";
/** The end line symbol. */
private static final String SYMBOL_END_LINE = "\n";
/** The request parameters symbol. */
private static final String SYMBOL_REQUEST = "?";
/** The blank string. */
private static final String BLANK_STRING = "";
/** The content type char set key. */
private static final String CONTENT_TYPE_CHARSET_KEY = "charset=";
/** The HTTP response code : OK */
private static final int HTTP_OK = 200;
/** HTTP request property : content type. */
private static final String CONTENT_TYPE = "Content-type";
/** HTTP request property : char set. */
private static final String CONTENT_KEY_CHATSET = "; charset=";
/**
* 构造方法
*/
private HttpConnectionUtil() {
}
public static String sendGetHttpRequest(String sendUrl) throws HttpConnectionException {
return sendGetHttpRequest(sendUrl, null, DEFAULT_CONNECT_TIMEOUTSECONDS, DEFAULT_READ_TIMEOUTSECONDS);
}
/**
* Send the HTTP request and return the response string.
*
* @param sendUrl The request URL, it should begin with 'http://' or 'https://'. If postUrl is null, return is null.
* @param sendParameters The request key-value parameters map. It could be null or empty.
* @param method The HTTP send message method. For example 'POST', 'GET'. Default is POST.
* @param charset The char set for coding and encoding string when send request and receive response. For example
* 'GBK', 'UTF-8'. Default is UTF-8.
* @param timeOutSeconds The connection time out in seconds. For example '10' means 10 seconds.
* @return The response string.
* @throws HttpConnectionException
*/
public static String sendGetHttpRequest(String sendUrl, String charset, long connetcTimeOutSeconds,
long readTimeOutSeconds) throws HttpConnectionException {
// validate send URL.
if (sendUrl == null || sendUrl.length() == 0) {
throw new HttpConnectionException("sendUrl不能为空");
}
String method = SEND_METHOD_GET;
if (charset == null || charset.trim().length() == 0) {
charset = CHARSET_UTF8;
}
if (connetcTimeOutSeconds == 0) {
connetcTimeOutSeconds = DEFAULT_CONNECT_TIMEOUTSECONDS;
}
if (readTimeOutSeconds == 0) {
readTimeOutSeconds = DEFAULT_READ_TIMEOUTSECONDS;
}
// send request.
HttpURLConnection conn = null;
String responseString = null;
try {
// build send message.
String sendMessage = BLANK_STRING;
// make URL.
URL url = buildURL(sendUrl, sendMessage, method);
// make HTTP connection.
conn = (HttpURLConnection) url.openConnection();
initConnection(conn, method, charset, connetcTimeOutSeconds * MILLI_SECOND, readTimeOutSeconds
* MILLI_SECOND);
// send request.
conn.connect();
if (method != null && SEND_METHOD_POST.equals(method) && sendMessage != null) {
OutputStream outStrm = conn.getOutputStream();
DataOutputStream out = new DataOutputStream(outStrm);
out.writeBytes(sendMessage);
out.flush();
out.close();
}
// build response string.
int respCode = conn.getResponseCode();
String responseCharset = conn.getContentType().substring(
conn.getContentType().indexOf(CONTENT_TYPE_CHARSET_KEY) + CONTENT_TYPE_CHARSET_KEY.length());
InputStream inStream = null;
if (respCode != HTTP_OK) {
// inStream = conn.getErrorStream();
// String responseMessage = readInputStream(inStream, responseCharset);
throw new HttpConnectionException("Http connection fail : [" + respCode + "] "
+ conn.getResponseMessage());
} else {
inStream = conn.getInputStream();
}
responseString = readInputStream(inStream, responseCharset);
} catch (IOException e) {
throw new HttpConnectionException("IOException异常", e);
} catch (Exception e) {
throw new HttpConnectionException("Exception异常", e);
} finally {
if (conn != null) {
conn.disconnect();
}
}
return responseString;
}
/**
* Read the input stream and build the message string.
*
* @param inStream
* @param charset
* @return
* @throws HttpConnectionException
*/
private static String readInputStream(InputStream inputStream, String charset) throws HttpConnectionException {
String response = null;
if (inputStream == null) {
throw new HttpConnectionException("Error Input Stream Parameter: null");
}
try {
BufferedInputStream bufferedinputstream = new BufferedInputStream(inputStream);
InputStreamReader isr = new InputStreamReader(bufferedinputstream, charset);
BufferedReader in = new BufferedReader(isr);
StringBuffer buff = new StringBuffer();
String readLine = null;
String endLine = SYMBOL_END_LINE;
while ((readLine = in.readLine()) != null) {
buff.append(readLine).append(endLine);
}
if (buff.length() > 0) {
response = buff.substring(0, buff.length() - 1);
} else {
response = buff.toString();
}
} catch (UnsupportedEncodingException e) {
throw new HttpConnectionException("Unsupported Encoding Exception: " + e);
} catch (IOException e) {
throw new HttpConnectionException("IOException: " + e);
}
return response;
}
/**
* Build URL for POST and GET method.
*
* @param URL
* @param message
* @param method
* @return
* @throws HttpConnectionException
*/
private static URL buildURL(String URL, String message, String method) throws HttpConnectionException {
URL url = null;
if (SEND_METHOD_GET.equals(method)) {
if (URL.indexOf(SYMBOL_REQUEST) > -1) {
try {
url = new URL(URL + SYMBOL_SEPERATOR + message);
} catch (MalformedURLException e) {
throw new HttpConnectionException("Create URL Error: " + e);
}
} else {
try {
url = new URL(URL + SYMBOL_REQUEST + message);
} catch (MalformedURLException e) {
throw new HttpConnectionException("Create URL Error: " + e);
}
}
} else if (SEND_METHOD_POST.equals(method)) {
try {
url = new URL(URL);
} catch (MalformedURLException e) {
throw new HttpConnectionException("Create URL Error: " + e);
}
} else {
throw new HttpConnectionException("Error Send Method Parameter: " + method);
}
return url;
}
/**
* Initial the connection for POST and GET method.
*
* @param connection
* @param method
* @param charset
* @param timeOut
* @throws HttpConnectionException
*/
private static void initConnection(HttpURLConnection connection, String method, String charset, Long connetTimeOut,
Long readTimeOut) throws HttpConnectionException {
if (connection == null) {
throw new HttpConnectionException("Error HttpURLConnection Parameter: null");
}
connection.setUseCaches(false);
connection.setDefaultUseCaches(false);
connection.setDoInput(true);
if (method != null && method.trim().length() > 0) {
try {
connection.setRequestMethod(method);
} catch (ProtocolException e) {
throw new HttpConnectionException("Set Request Method Error: " + e);
}
} else {
throw new HttpConnectionException("Error Method Parameter: " + method);
}
if (SEND_METHOD_POST.equals(method)) {
connection.setDoOutput(true);
if (charset != null && charset.trim().length() > 0) {
connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded; charset=" + charset);
} else {
throw new HttpConnectionException("Error Charset Parameter: " + charset);
}
}
if (connetTimeOut != null && readTimeOut != null) {
connection.setConnectTimeout(connetTimeOut.intValue());
connection.setReadTimeout(readTimeOut.intValue());
}
connection.setRequestProperty("User-Agent", "Mozilla/MSIE");
}
/**
* Send the HTTP request and return the response string.
*
* @param sendUrl The request URL, it should begin with 'http://' or 'https://'. The sendUrl should not be null.
* @param sendMessage The message for send. It could be null or empty.
* @return The response string.
* @throws IOException
* @throws HttpConnectionException
*/
public static String sendPostHttpRequest(String sendUrl, String sendMessage) throws IOException,
HttpConnectionException {
return sendHttpRequest(sendUrl, sendMessage, CONTENT_TYPE_APP_JSON, SEND_METHOD_POST, CHARSET_UTF8,
DEFAULT_CONNECT_TIMEOUTSECONDS, DEFAULT_READ_TIMEOUTSECONDS);
}
/**
* form表单形式请求
*
* @param sendUrl post请求的URL
* @param encodeParamters Encode之后的请求参数(注意:只对key和value进行encode,不要对等号进行encode),例如:key1=value1&key2=value2
* @return
* @throws IOException
* @throws HttpConnectionException
* @since 10.0
*/
public static String sendPostFormHttpRequest(String sendUrl, String encodeParamters) throws IOException,
HttpConnectionException {
return sendHttpRequest(sendUrl, encodeParamters, CONTENT_TYPE_FORM, SEND_METHOD_POST, CHARSET_UTF8,
DEFAULT_CONNECT_TIMEOUTSECONDS, DEFAULT_READ_TIMEOUTSECONDS);
}
/**
* Send the HTTP request and return the response string.
*
* @param sendUrl The request URL, it should begin with 'http://' or 'https://'. The sendUrl should not be null.
* @param sendMessage The message for send. It could be null or empty.
* @param contentType The content type of HTTP request head. The contentType should not be null.
* @param method The HTTP send message method. For example 'POST', 'GET'. Default is POST.
* @param charset The char set for coding and encoding string when send request and receive response. For example
* 'GBK', 'UTF-8'. Default is UTF-8.
* @return The response string.
* @throws IOException
* @throws HttpConnectionException
*/
public static String sendHttpRequest(String sendUrl, String sendMessage, String contentType, String method,
String charset) throws IOException, HttpConnectionException {
return sendHttpRequest(sendUrl, sendMessage, contentType, method, charset, DEFAULT_CONNECT_TIMEOUTSECONDS,
DEFAULT_READ_TIMEOUTSECONDS);
}
/**
* Send the HTTP request and return the response string.
*
* @param sendUrl The request URL, it should begin with 'http://' or 'https://'. The sendUrl should not be null.
* @param sendMessage The message for send. It could be null or empty.
* @param contentType The content type of HTTP request head. The contentType should not be null.
* @param method The HTTP send message method. For example 'POST', 'GET'. Default is POST.
* @param charset The char set for coding and encoding string when send request and receive response. For example
* 'GBK', 'UTF-8'. Default is UTF-8.
* @param connectTimeOutSeconds The connect time out in seconds. For example '10' means 10 seconds.
* @param readTimeOutSeconds The read time out in seconds. For example '10' means 10 seconds.
* @return The response string.
* @throws IOException
* @throws HttpConnectionException
*/
public static String sendHttpRequest(String sendUrl, String sendMessage, String contentType, String method,
String charset, long connectTimeOutSeconds, long readTimeOutSeconds) throws IOException,
HttpConnectionException {
// validate send URL.
if (sendUrl == null || sendUrl.length() == 0) {
throw new IOException("Request param error : sendUrl is null.");
}
if (method == null || method.trim().length() == 0) {
if (sendMessage == null || sendMessage.trim().length() == 0) {
method = SEND_METHOD_GET;
} else {
method = SEND_METHOD_POST;
}
}
if (SEND_METHOD_POST.equals(method) && (sendMessage == null || sendMessage.length() == 0)) {
throw new IOException("Request param error : sendMessage is null.");
}
if (contentType == null || contentType.length() == 0) {
throw new IOException("Request param error : contentType is null.");
}
if (charset == null || charset.trim().length() == 0) {
charset = CHARSET_UTF8;
}
// send request.
HttpURLConnection conn = null;
String responseString = null;
Map<String, List<String>> responseHeader = null;
try {
LOGGER.info("sendHttpRequest,参数:\n{}", sendMessage);
// make URL.
URL url = buildURL(sendUrl, sendMessage, method);
// make HTTP connection.
conn = (HttpURLConnection) url.openConnection();
initConnection(conn, method, contentType, charset, Long.valueOf(connectTimeOutSeconds * MILLI_SECOND),
Long.valueOf(readTimeOutSeconds * MILLI_SECOND));
// send request.
conn.connect();
if (method != null && SEND_METHOD_POST.equals(method) && sendMessage != null) {
OutputStream outStrm = conn.getOutputStream();
DataOutputStream out = new DataOutputStream(outStrm);
out.write(sendMessage.getBytes(charset));
out.flush();
out.close();
}
// build response string.
int respCode = conn.getResponseCode();
String responseCharset = charset;
if (conn.getContentType() != null && conn.getContentType().indexOf(CONTENT_TYPE_CHARSET_KEY) > 0) {
responseCharset = conn.getContentType().substring(
conn.getContentType().indexOf(CONTENT_TYPE_CHARSET_KEY) + CONTENT_TYPE_CHARSET_KEY.length());
responseCharset = formatCharset(responseCharset);
}
responseHeader = conn.getHeaderFields();
InputStream inStream = null;
if (respCode != HTTP_OK) {
inStream = conn.getErrorStream();
String responseMessage = readInputStream(inStream, responseCharset);
throw new IOException("Http connection fail : [" + respCode + "] " + conn.getResponseMessage() + "\n"
+ responseMessage);
} else {
inStream = conn.getInputStream();
responseString = readInputStream(inStream, responseCharset);
}
} catch (IOException e) {
throw new IOException("IOException: " + e + "\nURL = " + sendUrl + "\nParameter = "
+ sendMessage.toString() + "\nResponse Header = " + responseHeader);
} finally {
if (conn != null) {
conn.disconnect();
}
}
return responseString;
}
/**
* Initial the connection for POST and GET method.
*
* @param connection
* @param method
* @param contentType
* @param charset
* @param connectTimeOut
* @param readTimeOut
* @throws IOException
*/
private static void initConnection(HttpURLConnection connection, String method, String contentType, String charset,
Long connectTimeOut, Long readTimeOut) throws IOException {
Map<String, String> properties = new HashMap<String, String>();
if (method != null && SEND_METHOD_POST.equals(method)) {
if (contentType != null && contentType.trim().length() > 0) {
properties.put(CONTENT_TYPE, contentType);
if (charset != null && charset.trim().length() > 0) {
properties.put(CONTENT_TYPE, properties.get(CONTENT_TYPE) + CONTENT_KEY_CHATSET + charset);
}
}
}
initConnection(connection, method, properties, connectTimeOut, readTimeOut);
}
/**
* Initial the connection for POST and GET method.
*
* @param connection
* @param method
* @param requestProperties
* @param connectTimeOut
* @param readTimeOut
* @throws IOException
*/
private static void initConnection(HttpURLConnection connection, String method,
Map<String, String> requestProperties, Long connectTimeOut, Long readTimeOut) throws IOException {
if (connection != null) {
connection.setUseCaches(false);
connection.setDefaultUseCaches(false);
connection.setDoInput(true);
if (method != null && method.trim().length() > 0) {
try {
connection.setRequestMethod(method);
} catch (ProtocolException e) {
throw new IOException("Set Request Method Error: " + e);
}
if (SEND_METHOD_POST.equals(method)) {
connection.setDoOutput(true);
}
} else {
throw new IOException("Error Method Parameter: " + method);
}
if (requestProperties != null && requestProperties.size() > 0) {
String key, value;
for (Map.Entry<String, String> tempEntry : requestProperties.entrySet()) {
key = tempEntry.getKey();
value = tempEntry.getValue();
connection.setRequestProperty(key, value);
}
}
if (connectTimeOut != null && readTimeOut != null) {
System.setProperty("sun.net.client.defaultConnectTimeout", connectTimeOut.toString());
System.setProperty("sun.net.client.defaultReadTimeout", readTimeOut.toString());
connection.setConnectTimeout(connectTimeOut.intValue());
connection.setReadTimeout(readTimeOut.intValue());
}
connection.setRequestProperty("User-Agent", "Mozilla/MSIE");
} else {
throw new IOException("Error HttpURLConnection Parameter connection is null.");
}
}
/** Format the char-set string. */
private static String formatCharset(String responseCharset) {
String result = responseCharset;
if (result != null && result.length() > 0) {
result = result.trim();
result = result.replaceAll(";", "");
}
return result;
}
}