问题:
最近项目上面遇到和App对接,测试库他们使用的是 HTTP,但是正式库使用的是 HTTPS。之前没有做过,在网上找过好多文章,最后还是借鉴别人的,自己重新封装之后才在项目上面使用。
使用的jar的版本:
httpclient-4.3.1.jar
源码:
下面给出忽略证书的方式,因为App对接又不能给证书,并且证书是通过CA验证,只好通过此种方式去试试:
1.代码中用到的两个工具方法,以及请求的参数设置
private static final int SOCKET_TIME_OUT = 60000; // 设置读取超时
private static final int CONNECT_TIME_OUT = 60000; // 设置连接超时
/**
* 设置请求的参数值
* @return
*/
private static RequestConfig getRequestConfig() {
return RequestConfig.custom().setSocketTimeout(SOCKET_TIME_OUT).setConnectTimeout(CONNECT_TIME_OUT).build();
}
/**
* 设置参数列表
* @param param
* @return
*/
private static List<NameValuePair> createParam(Map<String, Object> param) {
List<NameValuePair> nvps = new ArrayList <NameValuePair>();
if(param != null) {
for(String k : param.keySet()) {
nvps.add(new BasicNameValuePair(k, param.get(k).toString()));
}
}
return nvps;
}
2.HTTPS 处理
2.1创建连接对象:
/**
* 创建一个SSL信任所有证书的httpClient对象
* @return
*/
public static CloseableHttpClient createSSLInsecureClient() {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
// 默认信任所有证书
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build();
// AllowAllHostnameVerifier: 这种方式不对主机名进行验证,验证功能被关闭,是个空操作(域名验证)
SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory(sslContext,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return HttpClients.custom().setSSLSocketFactory(sslcsf).build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
//如果创建失败,就创建一个默认的Http的连接
return HttpClients.createDefault();
}
2.2调用方法:
/**
* 无需本地证书keyStore的SSL https带参数请求
* post K - V 格式的数据
* @param url
* @param paramsMap
* @param encoding
* @return
*/
public static String postSSLParams(String url, Map<String, Object> params, Map<String, Object> headers) {
//创建一个信任的连接
CloseableHttpClient httpClient = createSSLInsecureClient();
//发送请求的实体类
HttpPost httpPost = new HttpPost(url);
//接收返回值
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try {
// 设置客户端请求的头参数getParams已经过时,现在用requestConfig对象替换
httpPost.setConfig(getRequestConfig());
//设置请求的头信息
Set<String> keys = headers.keySet();
for (String key : keys) {
httpPost.setHeader(key, headers.get(key).toString());
}
//这个是设置请求的类型,这个可能需要重点注意下,需要看对方接收的是什么
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
//添加参数, 设置编码格式
httpPost.setEntity(new UrlEncodedFormEntity( createParam(params) , Charset.forName("utf-8")));
//发送请求
HttpResponse response = httpClient.execute(httpPost);
//接收返回值
HttpEntity httpEntity = response.getEntity();
//返回值处理
br = new BufferedReader(new InputStreamReader(httpEntity.getContent(),"utf-8"));
String s = null;
while((s=br.readLine())!=null){
sb.append(s);
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + "utf-8");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
throw new RuntimeException("读取流文件异常",e);
}catch (Exception e) {
throw new RuntimeException("通讯未知系统异常",e);
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
3.调用HTTP的方法
3.1 发送 HTTP,K-V形式
/**
* 发送 POST 请求(HTTP),K-V形式
* @param url
* @param param
* @return
* @throws Exception
*/
public static String defaultPost(String url, Map<String, Object> param) throws Exception{
String returnString = "";
CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse response = null;
//设置字符集的两种方式
//new UrlEncodedFormEntity( createParam(params), Charset.forName("UTF-8"))
HttpEntity entity = new UrlEncodedFormEntity(createParam(param), Consts.UTF_8);
try {
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(getRequestConfig());
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpPost.setEntity(entity);
response = client.execute(httpPost);
returnString = EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(response.getEntity()); //关闭请求
return returnString;
} catch(Exception e) {
e.printStackTrace();
}
return returnString;
}
3.2 发送 HTTP,JSON形式
/**
* 发送 POST 请求(HTTP),JSON形式
* @param url 调用的地址
* @param jsonParams 调用的参数
* @return
* @throws Exception
*/
public static String postJson(String url, String jsonParams) throws Exception {
//创建一个默认的连接对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
HttpPost httpPost = new HttpPost(url);
String httpStr;
try {
StringEntity entity = new StringEntity(jsonParams);
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
response = httpClient.execute(httpPost);
httpStr = EntityUtils.toString(response.getEntity(), "UTF-8");
} finally {
if (response != null) {
EntityUtils.consume(response.getEntity());
}
}
return httpStr;
}
另外几点说明下:
1.由于我觉得get请求的方式实在是不安全,就没有去研究get。
2.以上是我在项目上面使用的,没有添加全部的代码,但是对应的方法都是可以使用的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。