微信给的demo中HttpsRequest笔者使用的时候不好使,索性只能以此为基础进行改造。
改造后的HttpsRequest如下:支持代理
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import com.tencent.service.IServiceRequest;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
/**
*
*/
public class HttpsRequests implements IServiceRequest
{
// 连接超时时间,默认10秒
private int socketTimeout = 10000;
// 传输超时时间,默认30秒
private int connectTimeout = 30000;
// HTTP请求器
private DefaultHttpClient httpClient;
public HttpsRequests() throws Exception
{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
// 根据规则查找商户对应证书
FileInputStream instream = new FileInputStream(new File(Configure.getCertLocalPath()));// 加载本地的证书进行https加密传输
try
{
// 证书密码默认为mchId
keyStore.load(instream, Configure.getCertPassword().toCharArray());// 设置证书密码
}
catch (Exception e)
{
throw new RuntimeException("init throw Exception", e);
}
finally
{
try
{
instream.close();
}
catch (IOException e)
{
}
}
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// 证书密码默认为mchId
SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore, Configure.getCertPassword());
socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme sch = new Scheme("https", socketFactory, 443);
registry.register(sch);
// 根据默认超时限制初始化requestConfig
HttpParams params = new BasicHttpParams();
params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectTimeout);
params.setParameter(CoreConnectionPNames.SO_TIMEOUT, socketTimeout);
httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(params, registry), params);
// //TODO 设置代理,生产环境需要去掉
// HttpHost proxy = new HttpHost("代理地址", 8080);
// CredentialsProvider credsProvider = new BasicCredentialsProvider();
// //TODO user\pwd改为代理用户密码
// UsernamePasswordCredentials creds = new UsernamePasswordCredentials("用户名", "密码");
// credsProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), creds);
// httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
// httpClient.setCredentialsProvider(credsProvider);
}
/**
* 通过Https往API post xml数据
*
* @param url
* API地址
* @param xmlObj
* 要提交的XML数据对象
* @return API回包的实际数据
* @throws IOException
* @throws KeyStoreException
* @throws UnrecoverableKeyException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public String sendPost(String url, Object xmlObj, int flag)
{
String result = null;
HttpPost httpPost = new HttpPost(url);
// 将要提交给API的数据对象转换成XML格式数据Post给API
String postDataXML = xmlObj.toString();
if (flag == 0)
{
XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
//将要提交给API的数据对象转换成XML格式数据Post给API
postDataXML = xStreamForRequestPostData.toXML(xmlObj);
}
try
{
// 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(postEntity);
HttpResponse response = ((HttpClient) httpClient).execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY)
{
Header locationHeader = response.getFirstHeader("location");
String location = null;
if (locationHeader != null)
{
location = locationHeader.getValue();
int index = location.indexOf("#");
String new_s = location.substring(0, index) + location.substring(index + 16);
return sendPost(new_s, xmlObj, flag);// 用跳转后的页面重新请求。
}
}
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
}
catch (Exception e)
{
throw new RuntimeException("http get throw Exception", e);
}
finally
{
httpPost.abort();
}
return result;
}
public static void main(String[] args) throws Exception
{
HttpsRequests hr = new HttpsRequests();
String r = hr.sendPost("", "");
System.out.println(r);
}
}
public interface IServiceRequest
{
//Service依赖的底层https请求器必须实现这么一个接口
public String sendPost(String api_url, Object xmlObj, int flag) throws UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, IOException;