- 空のGETリクエストがアドレスhttp:// localhost:8080 / loginに送信されます。
- サーバーは、ユーザー名とパスワードを入力するためのフォームを送信し、「JSESSIONID = 094BC0A489335CF8EE58C8E7846FE49B」というフォームのCookieも送信します。
- ユーザー名とパスワードを入力すると、先に受信したCookieと共に、POST要求がサーバーに送信されます。出力ストリームには「username = Fox&password = 123」という行が含まれています。ヘッダーは、「Content-Type:application / x-www-form-urlencoded」をさらに指定します。
- 応答として、サーバーは新しい「JSESSIONID =」を使用して新しいCookieを送信します。新しいCookieを使用したGETリクエストによって、http:// localhost:8080 /にすぐにリダイレクトされます。
- さらに、残りのサーバーAPIを安全に使用して、各リクエストで最後のCookieを渡すことができます。
これをJavaとPythonに実装する方法を見てみましょう。
コンテンツ
- Pythonの実装。リクエスト。
- Java、HttpURLConnection、CookieManagerでの実装。
- Java実装、CookieManagerなしのHttpURLConnection。
Pythonの実装。リクエスト
Pythonでネットワークを操作するためのライブラリーを選択するとき、ほとんどのサイトはリクエストライブラリーを推奨します。これはそのスローガンを完全に正当化します。
人間のためのHTTPタスク全体は、次のスクリプトによって解決されます。
import requests
session = requests.session() #
url = "http://localhost:8080/login"
session.get(url) # cookie
data = {"username": "Fox", "password": "123"}
response = session.post(url, data=data) #
Cookieとリダイレクト操作は、ブラウザと同じように、内部で行われることに注意してください。また、別の変数session2を作成すると、2つの接続を同時にアクティブに保つことができることにも注意してください。
Java、HttpURLConnection、CookieManagerでの実装
Javaでネットワーキングするためのライブラリーを検索すると、一度にいくつかのライブラリーが見つかります。
たとえば、java.net、Apache HttpClientおよびOkHttp3です。
HttpURLConnection(java.net)で解決しました。このライブラリの利点は、「すぐに使える」ライブラリであり、Android向けのアプリケーションを作成する必要がある場合は、公式Webサイトにドキュメントがあることです。欠点は、非常に大量のコードです。(Pythonの後で、それはただの苦痛です。)
それでは始めましょう。ドキュメントによると、CookieManagerを使用してセッションを操作できます:
CookieManager cookieManager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);
このアプローチを使用して注意すべき点:
- 「CookiePolicy.ACCEPT_ALL」は、すべてのCookieを使用する必要があることを示します。
- cookieManager変数は他の場所では使用されません。すべての接続を制御し、複数のアクティブセッションを維持する必要がある場合は、この1つの変数のCookieを手動で変更する必要があります。
これを念頭に置いて、1行で書くことができます。
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
パラグラフ1と2。最初のCookieを受信するためのGETリクエストを実行してみましょう。
URL url = new URL("http://localhost:8080/login");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
final StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
その後、cookieManagerにはサーバーからのcookieが含まれ、次のリクエストで自動的に置き換えられます。
楽しみはPOSTリクエストから始まります。
url = new URL("http://localhost:8080/login");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
ヘッダーに「Content-Type:application / x-www-form-urlencoded」と書き込む必要があります。
getHeaderFieldメソッドでメソッドがsetHeaders(またはaddHeaders)ではなく、setRequestPropertyと呼ばれるのはなぜでしょうか。
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
次に来るのはコードで、どのような理由でライブラリの内部で動かなくなるのかは不明です。
con.setDoOutput(true);
送信ストリームを開くには、このコード行が必要です。この行がないと、次のメッセージが表示されるのはおかしいです。
スレッド「メイン」の例外java.net.ProtocolException:doOutput = falseの場合、URLConnectionに書き込めません-setDoOutput(true)を呼び出します発信ストリームを開き、そこでログインとパスワードを書き留めます。
final DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes("username=Fox&password=123");
out.flush();
out.close();
すでに転送された要求からの応答を読み取るために残ります。
Java実装、CookieManagerなしのHttpURLConnection
CookieManagerなしで実装し、Cookieの動きを自分で制御できます。
ポイント1と2。クッキーを取り出します。
URL url = new URL("http://localhost:8080/login");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
final StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
String cookie = con.getHeaderField("Set-Cookie").split(";")[0];
}
次に、POSTリクエストを送信しますが、今回はCookieを挿入して自動リダイレクトを無効にします。その前に、新しいCookieを取得する時間が必要です。
//
url = new URL("http://localhost:8080/login");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
// headers cookie
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Cookie", cookie);
//
con.setInstanceFollowRedirects(false);
//
con.setDoOutput(true);
final DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes("username=Fox&password=123");
out.flush();
out.close();
// cookie
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
final StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
String cookie2 = con.getHeaderField("Set-Cookie").split(";")[0];
次に、すべてのリクエストに次の行を追加します。
con.setRequestProperty("Cookie", cookie2);
お役に立てば幸いです。コメントはより簡単なオプションを歓迎します。