Lakukan Permintaan HTTP Sederhana di Java

1. Ikhtisar

Dalam tutorial singkat ini, kami menyajikan cara melakukan permintaan HTTP di Java - dengan menggunakan kelas Java HttpUrlConnection bawaan.

Perhatikan bahwa dimulai dengan JDK 11, Java menyediakan API baru untuk melakukan permintaan HTTP, yang dimaksudkan sebagai pengganti HttpURLConnection, yang HttpClient API.

2. HttpUrlConnection

Kelas HttpUrlConnection memungkinkan kita melakukan permintaan HTTP dasar tanpa menggunakan pustaka tambahan apa pun. Semua kelas yang kita butuhkan adalah bagian dari paket java.net .

Kerugian menggunakan metode ini adalah kode bisa lebih rumit daripada pustaka HTTP lainnya dan tidak menyediakan fungsionalitas yang lebih canggih seperti metode khusus untuk menambahkan tajuk atau otentikasi.

3. Membuat Permintaan

Kita bisa membuat instance HttpUrlConnection menggunakan metode openConnection () dari kelas URL . Perhatikan bahwa metode ini hanya membuat objek koneksi tetapi belum membuat koneksi.

Kelas HttpUrlConnection digunakan untuk semua jenis permintaan dengan menyetel atribut requestMethod ke salah satu nilai: GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.

Mari buat koneksi ke URL tertentu menggunakan metode GET:

URL url = new URL("//example.com"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET");

4. Menambahkan Parameter Permintaan

Jika kita ingin menambahkan parameter ke permintaan, kita harus menyetel properti doOutput ke true , lalu menulis String dengan format param1 = value¶m2 = value ke OutputStream dari instance 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 memfasilitasi transformasi parameter Map , kami telah menulis kelas utilitas yang disebut ParameterStringBuilder yang berisi metode statis, getParamsString () , yang mengubah Map menjadi String dengan 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. Mengatur Header Permintaan

Menambahkan header ke permintaan bisa dilakukan dengan menggunakan metode setRequestProperty () :

con.setRequestProperty("Content-Type", "application/json");

Untuk membaca nilai header dari koneksi, kita bisa menggunakan metode getHeaderField () :

String contentType = con.getHeaderField("Content-Type");

6. Konfigurasi Timeout

Kelas HttpUrlConnection memungkinkan pengaturan waktu tunggu hubungkan dan baca. Nilai-nilai ini menentukan interval waktu menunggu koneksi ke server dibuat atau data tersedia untuk dibaca.

Untuk menyetel nilai batas waktu, kita bisa menggunakan metode setConnectTimeout () dan setReadTimeout () :

con.setConnectTimeout(5000); con.setReadTimeout(5000);

Dalam contoh, kami menetapkan kedua nilai batas waktu menjadi lima detik.

7. Menangani Cookies

The java.net paket berisi kelas yang nyaman bekerja dengan cookie seperti CookieManager dan HttpCookie .

Pertama, untuk membaca cookie dari sebuah respons , kita dapat mengambil nilai dari header Set-Cookie dan menguraikannya menjadi daftar objek HttpCookie :

String cookiesHeader = con.getHeaderField("Set-Cookie"); List cookies = HttpCookie.parse(cookiesHeader);

Selanjutnya, kami akan menambahkan cookie ke penyimpanan cookie :

cookies.forEach(cookie -> cookieManager.getCookieStore().add(null, cookie));

Mari kita periksa apakah ada cookie bernama nama pengguna , dan jika tidak, kami akan menambahkannya ke penyimpanan cookie 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")); }

Terakhir, untuk menambahkan cookie ke permintaan , kita perlu mengatur header Cookie , setelah menutup dan membuka kembali koneksi:

con.disconnect(); con = (HttpURLConnection) url.openConnection(); con.setRequestProperty("Cookie", StringUtils.join(cookieManager.getCookieStore().getCookies(), ";"));

8. Menangani Pengalihan

Kita dapat mengaktifkan atau menonaktifkan secara otomatis mengikuti pengalihan untuk koneksi tertentu dengan menggunakan metode setInstanceFollowRedirects () dengan parameter benar atau salah :

con.setInstanceFollowRedirects(false);

Dimungkinkan juga untuk mengaktifkan atau menonaktifkan pengalihan otomatis untuk semua koneksi :

HttpUrlConnection.setFollowRedirects(false);

Secara default, perilaku ini diaktifkan.

Ketika sebuah permintaan mengembalikan kode status 301 atau 302, yang menunjukkan pengalihan, kita 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 Respon

Membaca respons permintaan dapat dilakukan dengan mengurai InputStream dari instance HttpUrlConnection .

Untuk melaksanakan permintaan, kita dapat menggunakan getResponseCode () , menghubungkan () , getInputStream () atau getOutputStream () metode :

int status = con.getResponseCode();

Terakhir, mari kita membaca respon dari permintaan tersebut dan meletakkannya di dalam String konten :

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 koneksi , kita bisa menggunakan metode disconnect () :

con.disconnect(); 

10. Membaca Tanggapan atas Permintaan yang Gagal

Jika permintaan gagal, mencoba membaca InputStream dari instance HttpUrlConnection tidak akan berfungsi. Sebagai gantinya, kita bisa 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");

Selanjutnya, kita akan mendapatkan header menggunakan getHeaderFields () dan menambahkan masing-masing ke StringBuilder kita 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, kita akan membaca konten respon seperti yang kita lakukan sebelumnya dan menambahkannya.

Perhatikan bahwa metode getFullResponse akan memvalidasi apakah permintaan berhasil atau tidak untuk memutuskan apakah perlu menggunakan con.getInputStream () atau con.getErrorStream () untuk mengambil konten permintaan.

12. Kesimpulan

Dalam artikel ini, kami menunjukkan bagaimana kami dapat melakukan permintaan HTTP menggunakan kelas HttpUrlConnection .

Kode sumber lengkap dari contoh-contoh tersebut dapat ditemukan di GitHub.