java模拟httphttpspost请求

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

java模拟httphttpspost请求1.Post请求失败的代码
try {
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
Util.log("API,POST回来的数据是:");
Util.log(result);
} catch (ConnectionPoolTimeoutException e) {
log.e("http get throw ConnectionPoolTimeoutException(wait time out)");
} catch (ConnectTimeoutException e) {
log.e("http get throw ConnectTimeoutException");
} catch (SocketTimeoutException e) {
log.e("http get throw SocketTimeoutException");
} catch (Exception e) {
log.e("http get throw Exception");
} finally {
httpPost.abort();
}
之前每次代码执⾏到上述代码的第⼆⾏的时候,会等⼀段时间然后会捕获到Exception异常。

2.分析问题
当然捕获的Exception这个异常太⼤了我们不便于分析,我们查看⼀下httpClient.execute(HttpUriRequest uri)的⽅法;
发下这个⽅法会抛出IOException, ClientProtocolException这两个异常,但是在调⽤⽅法的时候并没有明确捕获他们两个。

3.得出结论
所以很有可能在执⾏post请求的过程中,遇到了这两个问题,果然我们把代码完善之后
try {
httpClient = new SSLClient();
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
Util.log("API,POST回来的数据是:");
Util.log(result);
} catch (ConnectionPoolTimeoutException e) {
log.e("http get throw ConnectionPoolTimeoutException(wait time out)");
} catch (ConnectTimeoutException e) {
log.e("http get throw ConnectTimeoutException");
} catch (SocketTimeoutException e) {
log.e("http get throw SocketTimeoutException");
} catch (ClientProtocolException e) {
log.e("http get throw ClientProtocolException");
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
log.e("http get throw Exception");
} finally {
httpPost.abort();
}
上述,完善完毕代码后捕捉到了IOException异常,我们把异常打印出来看到了如下信息。

4.解决问题
通过在⽹上查询可知,这是缺少安全证书时出现的异常,解决⽅案如下:
1. 等待Oracle/Google/Mozilla等等组织信任CNNIC,算了,洗洗睡吧
2. 使⽤Java的TrustManager忽略所有的SSL请求的证书,仅仅⽤于开发测试,限于篇幅不做介绍了
3. 导⼊⽬标⽹站的证书,然后在开始调⽤之前,指定keystore就ok了,本⽂介绍下该⽅法
⽬前我们采⽤第⼆种⽅案:由于请求的URL是HTTPS的,为了避免需要证书,所以⽤⼀个类继承DefaultHttpClient类,忽略校验过程。

编写⼀个SSLClient类
package com.phicomm.smarthome.sharedwifi.util;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import .ssl.SSLContext;
import .ssl.TrustManager;
import .ssl.X509TrustManager;
import org.apache.http.conn.ClientConnectionManager;
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.impl.client.DefaultHttpClient;
public class SSLClient extends DefaultHttpClient {
public SSLClient() throws Exception {
super();
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = this.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, ssf));
}
}
对应的实现类:
public HttpResponse sendPostToService(String url, Object pushData) throws IOException, KeyStoreException,
UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
if (!hasInit) {
init();
}
String result = null;
HttpPost httpPost = new HttpPost(url);
StringEntity postEntity = new StringEntity(pushData.toString(),
ContentType.create("application/x-www-form-urlencoded", "UTF-8"));
// 设置⼀些Http头信息
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
httpPost.addHeader("connection", "Keep-Alive");
httpPost.addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 将发送内容填装
httpPost.setEntity(postEntity);
// 设置请求器的配置
httpPost.setConfig(requestConfig);
// 打印待发送的数据
Util.log("=====API,POST过去的数据是:");
Util.log("executing request" + httpPost.getRequestLine());
Util.log("请求头信息===" + httpPost.getAllHeaders().toString());
Util.log("请求状态⾏===" + httpPost.getRequestLine());
Util.log("请求配置===" + httpPost.getConfig());
Util.log("请求实体===" + httpPost.getEntity().getContentEncoding() + httpPost.getEntity().getContentType()
+ httpPost.getEntity().getContent());
HttpResponse response = null;
try {
// 忽略所有的SSL请求的证书
httpClient = new SSLClient();
response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
// 打印得到的响应信息
Util.log("API,POST回来的数据是:");
Util.log("=====Entity:" + result);
Util.log("=====Headers:" + response.getAllHeaders());
Util.log("=====StatusLine:" + response.getStatusLine());
Util.log("=====Locale:" + response.getLocale());
} catch (ConnectionPoolTimeoutException e) {
log.e("http get throw ConnectionPoolTimeoutException(wait time out)");
} catch (ConnectTimeoutException e) {
log.e("http get throw ConnectTimeoutException");
} catch (SocketTimeoutException e) {
log.e("http get throw SocketTimeoutException");
} catch (ClientProtocolException e) {
log.e("http get throw ClientProtocolException");
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
log.e("http get throw Exception");
} finally {
httpPost.abort();
}
return response;
}
在第36⾏使⽤⾃定义的SSLClient来忽略掉验证要求
另外注意在postMan中模拟调⽤的时候我们是⽤的x-www-form-urlencoded格式的数据请求,就是application/x-www-from-urlencoded,会将表单内的数据转换为键值对。

当action为get时候,浏览器⽤x-www-form-urlencoded的编码⽅式把form数据转换成⼀个字串(name1=value1&name2=value2...),然后把这个字串append到url后⾯,⽤?分割,加载这个新的url。

当action为post时候,浏览器把form数据封装到http body中,然后发送到server。

所以我们需要对传进来的数据做⼀下处理:
// 拼接x-www-form-urlencoded格式的请求参数
String www_url = "coverimg=" + pushMsgModel.getCoverimg() + "&mode=" + pushMsgModel.getMode() + "&msgcontent="
+ pushMsgModel.getMsgContent() + "&msgtype=" + pushMsgModel.getMsgtype() + "&outline="
+ pushMsgModel.getOutline() + "&saveRecord=" + pushMsgModel.getSaveRecord() + "&source="
+ pushMsgModel.getSource() + "&ticker=" + pushMsgModel.getTicker() + "&timestamp="
+ pushMsgModel.getTimestamp() + "&title=" + pushMsgModel.getTitle() + "&uid=" + pushMsgModel.getUid()
+ "&url=" + pushMsgModel.getUrl();
("x-www-form-urlencoded格式的请求参数为:" + www_url);
最后效果如下:。

相关文档
最新文档