0708 post請求把引數放到報文訊息體中而不是拼接在url後面
阿新 • • 發佈:2019-01-22
post請求失敗
今天寫介面,在聯調。我要呼叫隊友php的介面資料,而要求使用post請求。
而當我寫好程式碼,跑起來,卻說我沒有傳參。最後發現,是因為我使用的工具類的方法是把引數拼到了url後面,而不是放到請求體中,所以導致拿不到資料。
我用的工具類的方法:
public static String doPost(String host, String path,
Map<String, String> querys)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPost request = new HttpPost(buildUrl(host, path, querys));
HttpResponse response = httpClient.execute(request);
int respCode = response.getStatusLine().getStatusCode();
if(respCode!=200){
return null;
}
return EntityUtils.toString(response.getEntity());
}
private static HttpClient wrapClient(String host) {
HttpClient httpClient = new DefaultHttpClient();
if (host.startsWith("https://")) {
sslClient(httpClient);
}
return httpClient;
}
private static void sslClient(HttpClient httpClient) {
try {
SSLContext ctx = SSLContext.getInstance("TLS" );
X509TrustManager tm = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] xcs, String str) {
}
@Override
public void checkServerTrusted(X509Certificate[] xcs, String str) {
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = httpClient.getConnectionManager();
SchemeRegistry registry = ccm.getSchemeRegistry();
registry.register(new Scheme("https", 443, ssf));
} catch (KeyManagementException ex) {
throw new RuntimeException(ex);
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
StringBuilder sbUrl = new StringBuilder();
sbUrl.append(host);
if (!StringUtils.isBlank(path)) {
sbUrl.append(path);
}
if (null != querys) {
StringBuilder sbQuery = new StringBuilder();
for (Map.Entry<String, String> query : querys.entrySet()) {
if (0 < sbQuery.length()) {
sbQuery.append("&");
}
if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
sbQuery.append(query.getValue());
}
if (!StringUtils.isBlank(query.getKey())) {
sbQuery.append(query.getKey());
if (!StringUtils.isBlank(query.getValue())) {
sbQuery.append("=");
sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
}
}
}
if (0 < sbQuery.length()) {
sbUrl.append("?").append(sbQuery);
}
}
return sbUrl.toString();
}
它就是把引數拼接到url上,而這樣子,當發起post請求,會拒絕了。說我沒有傳引數。
意思就是說,對方不會從url裡去取,而是從報文訊息體中取。
搞了好久都不成功,最終我找到了另一個代替的工具方法:
public static String getHttpResult(String path) throws IOException {
/*0、初始化要傳送的資料用list儲存*/
List<NameValuePair> list=new ArrayList<NameValuePair>();
String orderId = new Date().getTime() + "";
list.add(new BasicNameValuePair("Agent_SerialNo", orderId));
list.add(new BasicNameValuePair("Account_No", "21011000000053"));
list.add(new BasicNameValuePair("Balance", "1"));
list.add(new BasicNameValuePair("Service_Type", "6"));
/*1、通過path設定傳送方式*/
HttpPost post=new HttpPost(path);
/*2、建立客戶端*/
HttpClient client=new DefaultHttpClient();
//通過post表單方式傳送資料給伺服器
//建立表單
UrlEncodedFormEntity entity=new UrlEncodedFormEntity(list,"utf-8");
//裝載到post中
post.setEntity(entity);
HttpResponse response=client.execute(post);
/*3、得到輸入流*/
if(response.getStatusLine().getStatusCode()==200){
InputStream in=response.getEntity().getContent();
/*4、讀取流準備工作*/
ByteArrayOutputStream bos=new ByteArrayOutputStream();
byte[]arr=new byte [1024];
int len=0;
/*5、讀取並寫入*/
while((len=in.read(arr))!=-1){
bos.write(arr, 0, len);
}
byte[]b=bos.toByteArray();
return new String(b,0,b.length);
}
return null;
}