1. Gambaran keseluruhan
Dalam tutorial ringkas ini, kami menyajikan cara untuk melakukan permintaan HTTP di Java - dengan menggunakan HttpUrlConnection kelas Java bawaan.
Nota yang bermula dengan JDK 11, Java menyediakan API baru untuk melaksanakan permintaan HTTP, yang bertujuan sebagai pengganti untuk HttpUrlConnection, yang HttpClient API.
2. HttpUrlConnection
The HttpUrlConnection kelas membolehkan kita untuk melaksanakan permintaan asas HTTP tanpa menggunakan mana-mana perpustakaan tambahan. Semua kelas yang kami perlukan adalah sebahagian daripada pakej java.net .
Kelemahan menggunakan kaedah ini adalah bahawa kodnya dapat menjadi lebih rumit daripada perpustakaan HTTP lain dan tidak memberikan fungsi yang lebih maju seperti kaedah khusus untuk menambahkan tajuk atau pengesahan.
3. Membuat Permintaan
Kita boleh membuat HttpUrlConnection contoh menggunakan openConnection () kaedah yang URL kelas. Perhatikan bahawa kaedah ini hanya membuat objek sambungan tetapi belum membuat sambungan.
The HttpUrlConnection kelas digunakan untuk semua jenis permintaan dengan menetapkan requestMethod atribut kepada salah satu daripada nilai-nilai: GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
Mari buat sambungan ke URL yang diberikan menggunakan kaedah GET:
URL url = new URL("//example.com"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET");
4. Menambah Parameter Permintaan
Sekiranya kita ingin menambahkan parameter pada permintaan, kita harus menetapkan properti doOutput menjadi benar , kemudian tulis String dari bentuk param1 = value¶m2 = nilai ke OutputStream dari contoh HttpUrlConnection :
Map parameters = new HashMap(); parameters.put("param1", "val"); con.setDoOutput(true); DataOutputStream out = new DataOutputStream(con.getOutputStream()); out.writeBytes(ParameterStringBuilder.getParamsString(parameters)); out.flush(); out.close();
Untuk memudahkan transformasi parameter Peta , kami telah menulis kelas utiliti yang disebut ParameterStringBuilder yang mengandungi kaedah statik, getParamsString () , yang mengubah Peta menjadi Rentetan dari format yang diperlukan:
public class ParameterStringBuilder { public static String getParamsString(Map params) throws UnsupportedEncodingException{ StringBuilder result = new StringBuilder(); for (Map.Entry entry : params.entrySet()) { result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); result.append("="); result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); result.append("&"); } String resultString = result.toString(); return resultString.length() > 0 ? resultString.substring(0, resultString.length() - 1) : resultString; } }
5. Menetapkan Header Permintaan
Menambah tajuk untuk permintaan dapat dicapai dengan menggunakan kaedah setRequestProperty () :
con.setRequestProperty("Content-Type", "application/json");
Untuk membaca nilai header dari sambungan, kita dapat menggunakan kaedah getHeaderField () :
String contentType = con.getHeaderField("Content-Type");
6. Mengkonfigurasi Timeout
Kelas HttpUrlConnection membolehkan menetapkan batas waktu sambung dan baca. Nilai-nilai ini menentukan selang waktu untuk menunggu sambungan ke pelayan dibuat atau data tersedia untuk dibaca.
Untuk menetapkan nilai timeout, kita dapat menggunakan kaedah setConnectTimeout () dan setReadTimeout () :
con.setConnectTimeout(5000); con.setReadTimeout(5000);
Sebagai contoh, kami menetapkan kedua-dua nilai masa tamat hingga lima saat.
7. Mengendalikan Kuki
The java.net pakej mengandungi kelas yang selesa bekerja dengan cookies seperti CookieManager dan HttpCookie .
Pertama, untuk membaca kuki dari tindak balas , kita dapat mengambil nilai tajuk Set-Cookie dan menguraikannya ke senarai objek HttpCookie :
String cookiesHeader = con.getHeaderField("Set-Cookie"); List cookies = HttpCookie.parse(cookiesHeader);
Seterusnya, kami akan menambahkan kuki ke kedai kuki :
cookies.forEach(cookie -> cookieManager.getCookieStore().add(null, cookie));
Mari kita periksa sama ada cookie yang dipanggil nama pengguna ada, dan jika tidak, kami akan menambahkannya ke kedai kuki dengan nilai "john"
Optional usernameCookie = cookies.stream() .findAny().filter(cookie -> cookie.getName().equals("username")); if (usernameCookie == null) { cookieManager.getCookieStore().add(null, new HttpCookie("username", "john")); }
Akhirnya, untuk menambahkan kuki pada permintaan , kita perlu menetapkan tajuk Cookie , setelah menutup dan membuka semula sambungan:
con.disconnect(); con = (HttpURLConnection) url.openConnection(); con.setRequestProperty("Cookie", StringUtils.join(cookieManager.getCookieStore().getCookies(), ";"));
8. Mengendalikan Pengalihan
Kita boleh mengaktifkan atau mematikan pengalihan berikut secara automatik untuk sambungan tertentu dengan menggunakan kaedah setInstanceFollowRedirects () dengan parameter benar atau salah :
con.setInstanceFollowRedirects(false);
Anda juga boleh mengaktifkan atau mematikan pengalihan automatik untuk semua sambungan :
HttpUrlConnection.setFollowRedirects(false);
Secara lalai, tingkah laku diaktifkan.
Apabila permintaan mengembalikan kod status 301 atau 302, yang menunjukkan pengalihan, kami dapat mengambil tajuk Lokasi dan membuat permintaan baru ke URL baru:
if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM) { String location = con.getHeaderField("Location"); URL newUrl = new URL(location); con = (HttpURLConnection) newUrl.openConnection(); }
9. Membaca Respons
Membaca tindak balas permintaan boleh dilakukan dengan menguraikan InputStream dari contoh HttpUrlConnection .
Untuk melaksanakan permintaan itu, kita boleh menggunakan getResponseCode () , menyambung () , getInputStream () atau getOutputStream () kaedah :
int status = con.getResponseCode();
Akhirnya, mari baca jawapan permintaan dan letakkan dalam String kandungan :
BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer content = new StringBuffer(); while ((inputLine = in.readLine()) != null) { content.append(inputLine); } in.close();
Untuk menutup sambungan , kita boleh menggunakan kaedah putuskan () :
con.disconnect();
10. Membaca Respons pada Permintaan Yang Gagal
Sekiranya permintaan gagal, cuba membaca InputStream dari contoh HttpUrlConnection tidak akan berfungsi. Sebagai gantinya, kita boleh menggunakan aliran yang disediakan oleh HttpUrlConnection.getErrorStream () .
We can decide which InputStream to use by comparing the HTTP status code:
int status = con.getResponseCode(); Reader streamReader = null; if (status > 299) { streamReader = new InputStreamReader(con.getErrorStream()); } else { streamReader = new InputStreamReader(con.getInputStream()); }
And finally, we can read the streamReader in the same way as the previous section.
11. Building the Full Response
It's not possible to get the full response representation using the HttpUrlConnection instance.
However, we can build it using some of the methods that the HttpUrlConnection instance offers:
public class FullResponseBuilder { public static String getFullResponse(HttpURLConnection con) throws IOException { StringBuilder fullResponseBuilder = new StringBuilder(); // read status and message // read headers // read response content return fullResponseBuilder.toString(); } }
Here, we're reading the parts of the responses, including the status code, status message and headers, and adding these to a StringBuilder instance.
First, let's add the response status information:
fullResponseBuilder.append(con.getResponseCode()) .append(" ") .append(con.getResponseMessage()) .append("\n");
Seterusnya, kita akan mendapatkan tajuk menggunakan getHeaderFields () dan menambahkan masing-masing ke StringBuilder kami dalam format HeaderName: HeaderValues :
con.getHeaderFields().entrySet().stream() .filter(entry -> entry.getKey() != null) .forEach(entry -> { fullResponseBuilder.append(entry.getKey()).append(": "); List headerValues = entry.getValue(); Iterator it = headerValues.iterator(); if (it.hasNext()) { fullResponseBuilder.append(it.next()); while (it.hasNext()) { fullResponseBuilder.append(", ").append(it.next()); } } fullResponseBuilder.append("\n"); });
Akhirnya, kami akan membaca kandungan tindak balas seperti sebelumnya dan menambahkannya.
Perhatikan bahawa kaedah getFullResponse akan mengesahkan sama ada permintaan itu berjaya atau tidak untuk memutuskan apakah perlu menggunakan con.getInputStream () atau con.getErrorStream () untuk mengambil kandungan permintaan.
12. Kesimpulannya
Dalam artikel ini, kami menunjukkan bagaimana kami dapat melakukan permintaan HTTP menggunakan kelas HttpUrlConnection .
Kod sumber lengkap contoh boleh didapati di GitHub.