如何通过HttpsURLConnection将发布数据发送到https服务器

时间:2014-05-22 05:23:53

标签: java httpsurlconnection

我在网上看到了一个表单(https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx),如果我给选择搜索元素:注册号和输入搜索元素:作为AP31BF2942,如果我点击获取数据按钮,那么我得到了我的车辆详细信息。
我想在HttpsURLConnection中这样做  我在url的源代码中看到了参数名称为ctl00 $ OnlineContent $ ddlInput和ctl00 $ OnlineContent $ txtInput。

但是我无法获得所需的数据。请检查网址

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class TestAPHttp {

private final String USER_AGENT = "Mozilla/5.0";

public static void main(String[] args) throws Exception {

    TestAPHttp http = new TestAPHttp();


    System.out.println("\nTesting  - Send Http POST request");
    http.sendPost();

}



// HTTP POST request
private void sendPost() throws Exception {

    String url = "https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx";
    URL obj = new URL(url);
    HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

    //add reuqest header
    con.setRequestMethod("POST");
    con.setRequestProperty("User-Agent", USER_AGENT);
    con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

    String urlParameters = "ctl00$OnlineContent$ddlInput=R&ctl00$OnlineContent$txtInput=AP31BF2942";

    // Send post request
    con.setDoOutput(true);
    DataOutputStream wr = new DataOutputStream(con.getOutputStream());
    wr.writeBytes(urlParameters);
    wr.flush();
    wr.close();

    int responseCode = con.getResponseCode();
    System.out.println("\nSending 'POST' request to URL : " + url);
    System.out.println("Post parameters : " + urlParameters);
    System.out.println("Response Code : " + responseCode);

    BufferedReader in = new BufferedReader(
            new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();

    //print result
    System.out.println(response.toString());

}

}

1 个答案:

答案 0 :(得分:0)

而不是

DataOutputStream wr = new DataOutputStream(con.getOutputStream());

应该阅读

OutputStream wr = con.getOutputStream();

将字符串转换为byte[]时,您应该设置编码:

wr.write(urlParameters.getBytes("UTF-8"));

您应该设置Content-Type标题:

con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

顺便说一句,你正在“吃掉”收到文件的行尾。 readLine()读取下一个字符,直到行结束,但不会向您返回\n。您应该将它们附加到您的回复中。几乎在任何情况下,您都不应该使用StringBuffer,而是使用StringBuilder,但这与此帖完全无关,仅供您参考。

修改

我同时使用我的HTTP客户端库DavidWebb尝试了它,我设置了一些额外的标题,如User-Agent和所有缺少的形式参数,现在它可以工作:

Webb webb = Webb.create();
Response<String> response = webb
        .post("https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx")
        .header("User-Agent",
                "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/34.0.1847.116 Chrome/34.0.1847.116 Safari/537.36")
        .header("Accept", "*/*")
        .header("Origin", "https://aptransport.in")
        .header("Referer",
                "https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx")
        .header("X-MicrosoftAjax", "Delta=true")
        .param("ctl00$OnlineContent$ddlInput", "R")
        .param("ctl00$OnlineContent$txtInput", "AP31BF2942")
        .param("ctl00$OnlineContent$ScriptManager1",
                "ctl00$OnlineContent$Updatepanel1|ctl00$OnlineContent$btnGetData")
        .param("__EVENTTARGET", "")
        .param("__EVENTARGUMENT", "")
        .param("__VIEWSTATE",
                "/wEPDwUKMTE0MzI5ODM0MGRkdB0g7u2Z+Eg+a4Wr8QLkE1lzgSU=")
        .param("ctl00$OnlineContent$btnGetData", "Get Data")
        .connectTimeout(3000)
        .asString();

if (response.isSuccess()) {
    String result = response.getBody();
    System.out.println(result);
} else {
    System.out.println(response.getStatusCode());
    System.out.println(response.getResponseMessage());
    System.out.println(response.getErrorBody());
}

在很多情况下,模拟浏览器并使用HttpURLConnection不起作用或非常复杂(Cookie,客户端JavaScript,定时,特殊标题,跨站点请求伪造保护,。 ..)。在您的情况下,您很幸运,但是在您睡觉时,应用程序中的细微更改可能会破坏您的工作代码。

那我是怎么解决这个问题的?我使用Chrome的开发人员工具分析了网络流量(发送的标题和表单数据)(您也可以使用FireFox,Firebug,...)但是如果是HTTPS,它应该集成在浏览器中 - 您无法嗅探SSL使用wireshark加密的流量,例如

您可以在请求中看到,通过网络发送了更多标题和表单参数:

screenshot of developer tools