1. 程式人生 > >0708 post請求把引數放到報文訊息體中而不是拼接在url後面

0708 post請求把引數放到報文訊息體中而不是拼接在url後面

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;
    }