HttpsUrlConnection Android 与本机 Java
HttpsUrlConnection Android vs Native Java
我写了一些代码试图与网站 "as a browser" 通信(就 cookie 和 headers 而言)。我目前有四个请求(GET、POST、POST、GET)。
代码非常简单:打开连接,添加 headers 和 cookie,解析响应。
获取代码:
conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setUseCaches(false);
conn.setRequestProperty("User-Agent", userAgent);
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
if (cookies != null) {
for (String cookie : this.cookies) {
conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
}
}
int responseCode = conn.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
setCookies(conn.getHeaderFields().get("Set-Cookie"));
return response.toString();
POST代码:
conn = (HttpsURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Host", "...");
conn.setRequestProperty("User-Agent", userAgent);
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
conn.setRequestProperty("Accept-Encoding","identity");
for (String cookie : this.cookies) {
conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
}
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Referer", "https://...");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(postParams.length()));
conn.setDoOutput(true);
conn.setDoInput(true);
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();
int responseCode = conn.getResponseCode();
InputStream is = responseCode != 400 ? conn.getInputStream() : conn.getErrorStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
该程序在我的电脑上运行良好。但是,当 运行 在 Android 设备上安装它时,我在第二个 POST 上遇到多个问题 ;在一台设备上有 Too many redirections
异常,而在另一台设备(这是我关注的设备)上我只是收到 400 Bad Request
尽管在我的电脑上有完全相同的请求 returns 200。
我注意到实际上有两种不同的实现方式:在 PC 上我使用 sun.net.www.protocol.https.DelegateHttpsURLConnection
,而在 Android 上它是 com.android.okhttp.internal.http.HttpURLConnectionImpl
。 Object conn
在 运行 期间看起来有点不同。但是,我没能找到有意义的区别(如果需要,我可以post这些objects的全部内容);我发现第一个 GET 中设置的 cookie 有所不同,但手动操作导致相同的 400。
我尝试使用 Wireshark 捕获 Android 输出请求,但结果已加密,我未能成功解密。
我基本上想到了两种可能的场景:
- 找出这些实现之间的差异并采取相应行动。
- 想办法在 Android 上使用
sun.net.www.protocol.https.DelegateHttpsURLConnection
。
到目前为止我还没有弄清楚这些。这些实现是否有任何已知的 difference/issue?有没有办法 运行 Android 上的原生 Java 库?任何帮助将不胜感激,谢谢。
我写了一些代码试图与网站 "as a browser" 通信(就 cookie 和 headers 而言)。我目前有四个请求(GET、POST、POST、GET)。
代码非常简单:打开连接,添加 headers 和 cookie,解析响应。
获取代码:
conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setUseCaches(false);
conn.setRequestProperty("User-Agent", userAgent);
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
if (cookies != null) {
for (String cookie : this.cookies) {
conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
}
}
int responseCode = conn.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
setCookies(conn.getHeaderFields().get("Set-Cookie"));
return response.toString();
POST代码:
conn = (HttpsURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Host", "...");
conn.setRequestProperty("User-Agent", userAgent);
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
conn.setRequestProperty("Accept-Encoding","identity");
for (String cookie : this.cookies) {
conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
}
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Referer", "https://...");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(postParams.length()));
conn.setDoOutput(true);
conn.setDoInput(true);
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();
int responseCode = conn.getResponseCode();
InputStream is = responseCode != 400 ? conn.getInputStream() : conn.getErrorStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
该程序在我的电脑上运行良好。但是,当 运行 在 Android 设备上安装它时,我在第二个 POST 上遇到多个问题 ;在一台设备上有 Too many redirections
异常,而在另一台设备(这是我关注的设备)上我只是收到 400 Bad Request
尽管在我的电脑上有完全相同的请求 returns 200。
我注意到实际上有两种不同的实现方式:在 PC 上我使用 sun.net.www.protocol.https.DelegateHttpsURLConnection
,而在 Android 上它是 com.android.okhttp.internal.http.HttpURLConnectionImpl
。 Object conn
在 运行 期间看起来有点不同。但是,我没能找到有意义的区别(如果需要,我可以post这些objects的全部内容);我发现第一个 GET 中设置的 cookie 有所不同,但手动操作导致相同的 400。
我尝试使用 Wireshark 捕获 Android 输出请求,但结果已加密,我未能成功解密。
我基本上想到了两种可能的场景:
- 找出这些实现之间的差异并采取相应行动。
- 想办法在 Android 上使用
sun.net.www.protocol.https.DelegateHttpsURLConnection
。
到目前为止我还没有弄清楚这些。这些实现是否有任何已知的 difference/issue?有没有办法 运行 Android 上的原生 Java 库?任何帮助将不胜感激,谢谢。