package com.hx.mp.util;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
/**
* �Ƹ�ͨhttp����https����ͨ�ſͻ���
* ========================================================================
* api˵����
* setReqContent($reqContent),�����������ݣ�����post��get������get��ʽ�ṩ
* getResContent(), ��ȡӦ������
* setMethod(method),��������,post����get
* getErrInfo(),��ȡ������Ϣ
* setCertInfo(certFile, certPasswd),����֤�飬˫��httpsʱ��Ҫʹ��
* setCaInfo(caFile), ����CA����ʽδpem�����������
* setTimeOut(timeOut)�� ���ó�ʱʱ�䣬��λ��
* getResponseCode(), ȡ���ص�http״̬��
* call(),������ýӿ�
* getCharset()/setCharset(),�ַ����
*
* ========================================================================
*
*/
public class TenpayHttpClient {
private static final String USER_AGENT_VALUE =
"Mozilla/4.0 (compatible; MSIE 6.0; Windows XP)";
private static final String JKS_CA_FILENAME =
"tenpay_cacert.jks";
private static final String JKS_CA_ALIAS = "tenpay";
private static final String JKS_CA_PASSWORD = "";
/** ca֤���ļ� */
private File caFile;
/** ֤���ļ� */
private File certFile;
/** ֤������ */
private String certPasswd;
/** �������ݣ�����post��get������get��ʽ�ṩ */
private String reqContent;
/** Ӧ������ */
private String resContent;
/** ���� */
private String method;
/** ������Ϣ */
private String errInfo;
/** ��ʱʱ��,����Ϊ��λ */
private int timeOut;
/** httpӦ����� */
private int responseCode;
/** �ַ���� */
private String charset;
private InputStream inputStream;
private RequestHandler reqHandler;//方便取值所用(quan)
/*public TenpayHttpClient() {
this.caFile = null;
this.certFile = null;
this.certPasswd = "";
this.reqContent = "";
this.resContent = "";
this.method = "POST";
this.errInfo = "";
this.timeOut = 30;//30��
this.responseCode = 0;
this.charset = "UTF-8";
this.inputStream = null;
}*/
public TenpayHttpClient() {
this.caFile = null;
this.certFile = null;
this.certPasswd = "";
this.reqContent = "";
this.resContent = "";
this.method = "POST";
this.errInfo = "";
this.timeOut = 30;//30��
this.responseCode = 0;
this.charset = "UTF-8";
this.inputStream = null;
}
/**
* ����֤����Ϣ
* @param certFile ֤���ļ�
* @param certPasswd ֤������
*/
public void setCertInfo(File certFile, String certPasswd) {
this.certFile = certFile;
this.certPasswd = certPasswd;
}
/**
* ����ca
* @param caFile
*/
public void setCaInfo(File caFile) {
this.caFile = caFile;
}
/**
* ������������
* @param reqContent ��������
*/
public void setReqContent(String reqContent) {
this.reqContent = reqContent;
}
/**
* ��ȡ�������
* @return String
* @throws IOException
*/
public String getResContent() {
try {
this.doResponse();
} catch (IOException e) {
this.errInfo = e.getMessage();
//return "";
}
return this.resContent;
}
/**
* ��������post����get
* @param method ����post/get
*/
public void setMethod(String method) {
this.method = method;
}
/**
* ��ȡ������Ϣ
* @return String
*/
public String getErrInfo() {
return this.errInfo;
}
/**
* ���ó�ʱʱ��,����Ϊ��λ
* @param timeOut ��ʱʱ��,����Ϊ��λ
*/
public void setTimeOut(int timeOut) {
this.timeOut = timeOut;
}
/**
* ��ȡhttp״̬��
* @return int
*/
public int getResponseCode() {
return this.responseCode;
}
/**
* ִ��http���á�true:�ɹ� false:ʧ��
* @return boolean
*/
/* public boolean call() {
boolean isRet = false;
//http
if(null == this.caFile && null == this.certFile) {
System.out.println("没有CA");
try {
this.callHttp();
isRet = true;
} catch (IOException e) {
this.errInfo = e.getMessage();
}
return isRet;
}
//https
try {
this.callHttps();
isRet = true;
} catch (UnrecoverableKeyException e) {
this.errInfo = e.getMessage();
} catch (KeyManagementException e) {
this.errInfo = e.getMessage();
} catch (CertificateException e) {
this.errInfo = e.getMessage();
} catch (KeyStoreException e) {
this.errInfo = e.getMessage();
} catch (NoSuchAlgorithmException e) {
this.errInfo = e.getMessage();
} catch (IOException e) {
this.errInfo = e.getMessage();
}
return isRet;
}*/
/**
* ִ��http���á�true:�ɹ� false:ʧ��
* @return boolean
*/
public boolean call() {
boolean isRet = false;
//http
if(null == this.caFile && null == this.certFile) {
System.out.println("没有CA");
try {
this.callHttp();
isRet = true;
} catch (IOException e) {
this.errInfo = e.getMessage();
}
return isRet;
}
//https
try {
this.callHttps();
isRet = true;
} catch (UnrecoverableKeyException e) {
this.errInfo = e.getMessage();
} catch (KeyManagementException e) {
this.errInfo = e.getMessage();
} catch (CertificateException e) {
this.errInfo = e.getMessage();
} catch (KeyStoreException e) {
this.errInfo = e.getMessage();
} catch (NoSuchAlgorithmException e) {
this.errInfo = e.getMessage();
} catch (IOException e) {
this.errInfo = e.getMessage();
}
return isRet;
}
protected void callHttp() throws IOException {
if("POST".equals(this.method.toUpperCase())) {
String url = HttpClientUtil.getURL(this.reqContent);
System.out.println("tenpayHttpClient:url:"+url);
//String queryString = HttpClientUtil.getQueryString(this.reqContent);
//byte[] postData = queryString.getBytes(this.charset);
String queryString = createXmlPosData();
byte[] postData = queryString.getBytes(this.charset);
this.httpPostMethod(url, postData);
return ;
}
this.httpGetMethod(this.reqContent);
}
protected void callHttps() throws IOException, CertificateException,
KeyStoreException, NoSuchAlgorithmException,
UnrecoverableKeyException, KeyManagementException {
// caĿ¼
String caPath = this.caFile.getParent();
System.out.println("caPath:"+caPath);
File jksCAFile = new File(caPath + "/"
+ TenpayHttpClient.JKS_CA_FILENAME);
if (!jksCAFile.isFile()) {
X509Certificate cert = (X509Certificate) HttpClientUtil
.getCertificate(this.caFile);
FileOutputStream out = new FileOutputStream(jksCAFile);
// store jks file
HttpClientUtil.storeCACert(cert, TenpayHttpClient.JKS_CA_ALIAS,
TenpayHttpClient.JKS_CA_PASSWORD, out);
out.close();
}
FileInputStream trustStream = new FileInputStream(jksCAFile);
FileInputStream keyStream = new FileInputStream(this.certFile);
SSLContext sslContext = HttpClientUtil.getSSLContext(trustStream,
TenpayHttpClient.JKS_CA_PASSWORD, keyStream, this.certPasswd);
//�ر���
keyStream.close();
trustStream.close();
if("POST".equals(this.method.toUpperCase())) {
String url = HttpClientUtil.getURL(this.reqContent);
//原本是直接参数转为字节数组的,现在组拼xml
//String queryString = HttpClientUtil.getQueryString(this.reqContent);//获取链接下面的内容
//byte[] postData = queryString.getBytes(this.charset);//把参数转为字节数组
//先获取参数
String queryString = createXmlPosData();
byte[] postData = queryString.getBytes(this.charset);//把参数转为字节数组
this.httpsPostMethod(url, postData, sslContext);
return ;
}
this.httpsGetMethod(this.reqContent, sslContext);
}
/**
* ��http post��ʽͨ��
* @param url
* @param postData
* @throws IOException
*/
protected void httpPostMethod(String url, byte[] postData)
throws IOException {
HttpURLConnection conn = HttpClientUtil.getHttpURLConnection(url);
this.doPost(conn, postData);
}
/**
* ��http get��ʽͨ��
*
* @param url
* @throws IOException
*/
protected void httpGetMethod(String url) throws IOException {
HttpURLConnection httpConnection =
HttpClientUtil.getHttpURLConnection(url);
this.setHttpRequest(httpConnection);
httpConnection.setRequestMethod("GET");
this.responseCode = httpConnection.getResponseCode();
this.inputStream = httpConnection.getInputStream();
}
/**
* ��https get��ʽͨ��
* @param url
* @param sslContext
* @throws IOException
*/
protected void httpsGetMethod(String url, SSLContext sslContext)
throws IOException {
SSLSocketFactory sf = sslContext.getSocketFactory();
HttpsURLConnection conn = HttpClientUtil.getHttpsURLConnection(url);
conn.setSSLSocketFactory(sf);
this.doGet(conn);
}
//提交https post 数据 s
protected void httpsPostMethod(String url, byte[] postData,
SSLContext sslContext) throws IOException {
SSLSocketFactory sf = sslContext.getSocketFactory();
HttpsURLConnection conn = HttpClientUtil.getHttpsURLConnection(url);
conn.setSSLSocketFactory(sf);
this.doPost(conn, postData);
}
/**
* ����http����Ĭ������
* @param httpConnection
*/
protected void setHttpRequest(HttpURLConnection httpConnection) {
//�������ӳ�ʱʱ��
httpConnection.setConnectTimeout(this.timeOut * 1000);
//User-Agent
httpConnection.setRequestProperty("User-Agent",
TenpayHttpClient.USER_AGENT_VALUE);
//��ʹ�û���
httpConnection.setUseCaches(false);
//�����������
httpConnection.setDoInput(true);
httpConnection.setDoOutput(true);
}
/**
* ����Ӧ��
* @throws IOException
*/
protected void doResponse() throws IOException {
if(null == this.inputStream) {
return;
}
//��ȡӦ������
this.resContent=HttpClientUtil.InputStreamTOString(this.inputStream,this.charset);
// System.out.println("tenpayHttpClinet:385:"+resContent);
//�ر�������
this.inputStream.close();
}
/**
* post��ʽ����
* @param conn
* @param postData
* @throws IOException
*/
protected void doPost(HttpURLConnection conn, byte[] postData)
throws IOException {
// ��post��ʽͨ��
conn.setRequestMethod("POST");
// ��������Ĭ������
this.setHttpRequest(conn);
// Content-Type
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
BufferedOutputStream out = new BufferedOutputStream(conn
.getOutputStream());
final int len = 1024; // 1KB
HttpClientUtil.doOutput(out, postData, len);
// �ر���
out.close();
// ��ȡ��Ӧ����״̬��
this.responseCode = conn.getResponseCode();
// ��ȡӦ��������
this.inputStream = conn.getInputStream();
}
/**
* get��ʽ����
* @param conn
* @throws IOException
*/
protected void doGet(HttpURLConnection conn) throws IOException {
//��GET��ʽͨ��
conn.setRequestMethod("GET");
//��������Ĭ������
this.setHttpRequest(conn);
//��ȡ��Ӧ����״̬��
this.responseCode = conn.getResponseCode();
//��ȡӦ��������
this.inputStream = conn.getInputStream();
}
public void setRequestHandler(RequestHandler reqHandler) {
this.reqHandler = reqHandler;
}
//组建xml格式传递参数
@SuppressWarnings({ "rawtypes", "unused" })
public String createXmlPosData(){
//先获取参数
Document document = DocumentHelper.createDocument();
Element root = document.addElement("xml");
if(reqHandler==null)throw new RuntimeException("请先设入reqHandler");
SortedMap parameters = reqHandler.getAllParameters();
Set es = reqHandler.getAllParameters().entrySet();
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
Element ToUserName = root.addElement(k);
ToUserName.addText(v);
}
String queryString = document.asXML();//转为String
queryString = queryString.replace("", "").trim();
System.out.println("xml:"+queryString);
return queryString;
}
}