Java 如何通过 HttpsURLConnection 将 Post 数据发送到 https 服务器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23798402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to send Post Data to https server via HttpsURLConnection
提问by LMK
I saw a form (https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx) in web, if i give Select Search Element: as Registration No and Enter Search Element: as AP31BF2942 ,and if i click on get data button, then i am getting my vehicle Details.
I want to do this in HttpsURLConnection.
I have seen parameter names as ctl00$OnlineContent$ddlInput and ctl00$OnlineContent$txtInput in the source of url.
我在网上看到了一个表格(https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx),如果我给 Select Search Element: as Registration No 并输入 Search Element: as AP31BF2942 ,如果我点击 get data 按钮,然后我会得到我的车辆详细信息。
我想在 HttpsURLConnection 中做到这一点。
我在 url 源中看到参数名称为 ctl00$OnlineContent$ddlInput 和 ctl00$OnlineContent$txtInput。
But i am unable to get required data.Please check the url
但我无法获得所需的数据。请检查网址
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());
}
}
采纳答案by hgoebl
Instead of
代替
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
it should read
它应该读
OutputStream wr = con.getOutputStream();
When converting a String to byte[]
you should set the encoding:
将字符串转换为byte[]
您应该设置编码:
wr.write(urlParameters.getBytes("UTF-8"));
And you should set the Content-Type
header:
你应该设置Content-Type
标题:
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
BTW you're "eating" the line endings of the received document. readLine()
reads the next characters until line ending, but doesn't return \n
to you. You should append them to your response. And in almost any case you shouldn't use StringBuffer
, but StringBuilder
, but this has absolutely nothing to do with this post and is only for your information.
顺便说一句,您正在“吃掉”收到的文档的行尾。readLine()
读取下一个字符直到行结束,但不会返回\n
给您。您应该将它们附加到您的回复中。几乎在任何情况下,您都不应该使用StringBuffer
, but StringBuilder
,但这与这篇文章完全无关,仅供您参考。
Edit
编辑
I tried it in the meanwhile with my HTTP client library DavidWebband I set some additional headers like User-Agent
and all missing form params and now it works:
我同时使用我的 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());
}
There are many cases, where simulating a browser and using HttpURLConnection
doesn't work or is very complicated (Cookies, client-side JavaScript, Timing, special headers, Cross-Site-Request-Forgery protection, ...). In your case, you have luck, but small changes in the application might break your working code while you're sleeping.
在许多情况下,模拟浏览器并使用HttpURLConnection
不起作用或非常复杂(Cookie、客户端 JavaScript、计时、特殊标头、跨站点请求伪造保护等)。在您的情况下,您很幸运,但应用程序中的微小更改可能会在您睡觉时破坏您的工作代码。
So how did I solve the problem? I analyzed the network traffic (sent headers and form data) with Chrome's developer tools (you can as well use FireFox, Firebug, ...) but in case of HTTPS it should be integrated in the browser - you can't sniff the SSL encrypted traffic with wireshark
e.g.
那么我是如何解决这个问题的呢?我使用 Chrome 的开发工具(您也可以使用 FireFox、Firebug 等)分析了网络流量(发送的标头和表单数据),但在 HTTPS 的情况下,它应该集成到浏览器中 - 您无法嗅探 SSL加密流量,wireshark
例如
You can see in the request, that many more headers and form parameters are sent across the wire:
您可以在请求中看到,通过网络发送了更多的标头和表单参数: