ウェブサイト(「クッキー」という言葉では&ヘッダー)と通信しようとするコードを書きました。私は現在4つのリクエスト(GET、POST、POST、GET)を持っています。HttpsUrlConnection Android vsネイティブJava
コードはかなり簡単です。接続を開いたり、ヘッダーとCookieを追加したり、応答を解析したりします。
GETコード:
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();
プログラムは、私のPCに適しています。しかし、それをAndroidデバイスで実行すると、2番目のPOSTに複数の問題があります。 1つのデバイスにはToo many redirections
の例外があり、別の1つ(私が重点を置いているのはもう1つ)では、全く同じ要求が自分のPCに200を返しますが、400 Bad Request
を受け取るだけです。
私は実際には2つの異なる実装があることに気付きました:私はsun.net.www.protocol.https.DelegateHttpsURLConnection
を使用しています.PCでは、com.android.okhttp.internal.http.HttpURLConnectionImpl
です。オブジェクトconn
は実行時に少し違って見えます。しかし、私は意味のある違いを見つけることができませんでした(必要であれば、これらのオブジェクトの全内容を投稿できます)。最初のGETに設定されたクッキーに1つの違いが見つかりましたが、手作業で同じ操作が行われました。
Wiresharkを使用してAndroid出力リクエストを取得しようとしましたが、結果は暗号化されていましたそれを解読する。
は、私は基本的に2つの可能なシナリオを考える:
- は、それらの実装の差(複数可)を検索し、それに応じて行動します。
- Androidで
sun.net.www.protocol.https.DelegateHttpsURLConnection
を使用する方法を見つける。
これまでのところ、私はこれらのどれも把握できませんでした。これらの実装との違いは何か? AndroidにネイティブJavaライブラリを実行する方法はありますか?助けていただければ幸いです。
ログを使用して、推奨あるいは全くヘッダがだまされなかったり、余分なヘッダが存在していることを確認しています。 http://stackoverflow.com/questions/22173517/httpurlconnection-wire-logging-in-androidそして本体の生のバイトを「ライター」でエンコードしてみてください。最後のポイントは、バイト配列をストリームに変換するようなものです。 –
出力ストリームを取得する前にヘッダーを記録すると、ヘッダーを要求するときに暗黙的にストリームが取得されるため、例外が発生します。 「Watches」ウィンドウで同様のことをチェックするときも同じことが起こりました。 –
2つ目のアドバイスに関しては、私は現在、POSTリクエストの入力パラメータに対してのみこれを行っています(変数 'postParams'を参照)。 JSoupの使用私はすべての要素に 'input'タグを付け、' URLEncoder.encode'でエンコーディングした後にそれらを連結します。あなたはこの問題に何か他に何かすると思いますか? –