Menghubungkan ke sesi di Jawa dan Python. HttpURLConnection dan CookieManager (Java). Permintaan (Python)

Katakanlah kita perlu terhubung ke server, masuk dan kelola sesi. Di browser, tampilannya seperti ini:



  1. Permintaan GET kosong dikirim ke alamat http: // localhost: 8080 / login .
  2. Server mengirimkan formulir untuk mengisi nama pengguna dan kata sandi, dan juga mengirimkan cookie dari formulir "JSESSIONID = 094BC0A489335CF8EE58C8E7846FE49B".
  3. Setelah mengisi nama pengguna dan kata sandi, permintaan POST dikirim ke server dengan Cookie yang diterima sebelumnya, dengan baris di aliran keluaran "username = Fox & password = 123". Tajuk tambahan menetapkan "Tipe-Konten: application / x-www-form-urlencoded".
  4. Sebagai tanggapan, server mengirimi kami cookie baru dengan "JSESSIONID =" baru. Segera dialihkan ke http: // localhost: 8080 / dengan MENDAPATKAN permintaan dengan Cookie baru.
  5. Selanjutnya, Anda dapat menggunakan API server lainnya dengan aman, meneruskan cookie terakhir di setiap permintaan.


Mari kita lihat bagaimana ini dapat diimplementasikan dalam Java dan Python.







Kandungan





Implementasi python. Persyaratan



Saat memilih perpustakaan untuk bekerja dengan jaringan di Python, sebagian besar situs akan merekomendasikan perpustakaan permintaan yang sepenuhnya membenarkan slogannya:

HTTP untuk Manusia
Seluruh tugas diselesaikan dengan skrip berikut:



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) #


Perhatikan bahwa manipulasi cookie dan pengalihan terjadi di bawah tenda, sama seperti di browser. Dapat juga dicatat bahwa jika Anda membuat variabel lain session2 , maka Anda dapat menjaga dua koneksi sekaligus.



Implementasi Java, HttpURLConnection dan CookieManager



Pencarian perpustakaan untuk jaringan di Jawa mengarah ke beberapa perpustakaan sekaligus.



Misalnya java.net , Apache HttpClient dan OkHttp3 .



Saya memilih HttpURLConnection (java.net). Kelebihan dari perpustakaan ini adalah bahwa perpustakaan ini adalah out-of-box , dan juga, jika Anda perlu menulis aplikasi untuk android, ada dokumentasi di situs web resmi . Kelemahannya adalah jumlah kode yang sangat besar. (Setelah Python, itu hanya menyakitkan.)



Jadi, mari kita mulai. Menurut dokumentasi untuk bekerja dengan sesi, Anda dapat menggunakan CookieManager :



CookieManager cookieManager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);


Hal-hal yang perlu diperhatikan menggunakan pendekatan ini:



  • "CookiePolicy.ACCEPT_ALL" menunjukkan bahwa Anda harus bekerja dengan semua cookie.
  • Variabel cookieManager tidak akan digunakan di tempat lain. Ini mengontrol semua koneksi, dan jika Anda perlu mendukung beberapa sesi aktif, Anda perlu mengganti cookie dalam variabel yang satu ini dengan tangan Anda


Dengan ini, Anda dapat menulis dalam satu baris:



 CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));


Poin 1 dan 2. Mari kita jalankan permintaan GET untuk mendapatkan Cookie pertama:



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);
}


Setelah itu, CookieManager kami akan berisi cookie dari server dan secara otomatis akan menggantikannya dalam permintaan berikutnya.



Kesenangan dimulai dengan permintaan POST.



url = new URL("http://localhost:8080/login");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");


Anda perlu menulis di Tajuk "Tipe-Konten: application / x-www-form-urlencoded".



Mengapa metode ini disebut setRequestProperty, dan bukan setHeaders (atau addHeaders) dengan metode getHeaderField, tetap menjadi misteri.



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


Berikutnya adalah kode, yang, untuk beberapa alasan, tidak terselip di bawah kap perpustakaan.



con.setDoOutput(true);


Baris kode ini diperlukan untuk membuka aliran keluar. Sangat lucu bahwa tanpa baris ini kita mendapatkan pesan berikut:



Pengecualian di utas "utama" java.net.ProtocolException: tidak dapat menulis ke URLConnection jika doOutput = false - panggil setDoOutput (true)

Buka aliran keluar dan tulis nama pengguna dan kata sandi di sana:



final DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes("username=Fox&password=123");
out.flush();
out.close();


Masih membaca tanggapan dari permintaan yang sudah diteruskan.



Implementasi Java, HttpURLConnection tanpa CookieManager



Anda dapat menerapkannya tanpa CookieManager dan mengontrol sendiri pergerakan cookie.

Poin 1 dan 2. Kami mengeluarkan cookie.



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];
}


Selanjutnya, kami mengirim permintaan POST, hanya kali ini dengan memasukkan cookie dan menonaktifkan pengalihan otomatis, karena sebelum itu, Anda harus punya waktu untuk mengeluarkan cookie baru:



//  
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];


Selanjutnya, kami cukup menambahkan baris berikut ke semua permintaan:



con.setRequestProperty("Cookie", cookie2);


Semoga bermanfaat. Opsi yang lebih sederhana dipersilakan di komentar.



All Articles