Halo
Hari ini saya akan mencoba untuk berbicara tentang bagaimana Anda dapat mengirim permintaan dan membaca tanggapan dari server HTTP menggunakan URLConnection dari perpustakaan JRE.
Kami sedang belajar Java online. Seluruh tim kami menggunakan Slack untuk bekerja dan berkomunikasi. Untuk informasi tentang pengguna, kami menggunakan Slack API. Agar tidak berbicara tentang API itu sendiri untuk waktu yang lama (ini adalah topik untuk artikel terpisah), saya akan mengatakan secara singkat: Slack API dibangun pada protokol HTTP, untuk mendapatkan informasi tentang pengguna, Anda harus mengirim permintaan dengan URI di mana harus ada nama metode dari API ke alamat host
api. slack.com Berikut adalah daftar beberapa metode:
- users.list
- chat.postMessage
- percakapan.buat
- files.upload
- buka
Untuk mendapatkan daftar pengguna, Anda memerlukan metode users.list. Kami membentuk URI -
/api/users.list di badan permintaan harus ada token otentikasi dalam formulir aplikasi / x-www-form-urlencoded, yaitu, permintaan akan terlihat seperti ini (tetapi ada satu nuansa yang akan lebih rendah):
GET /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5
Saya tahu tentang perpustakaan Apache HttpComponents, tetapi untuk tujuan penelitian kami akan menggunakan alat yang tersedia di perpustakaan Java 8 standar, yaitu implementasi java.net.URLConnection.
Untuk mendapatkan entitas URLConnection, Anda perlu menggunakan objek dari kelas java.net.URL, konstruktornya mengambil tipe String di mana, selain semuanya, protokol harus ditentukan - dalam kasus kami, https.
Setelah menerima entitas URL, kami memanggil metode
openConnection () yang akan mengembalikan entitas HttpsUrlConnection.
String url = “https:
Dalam hal ini, Anda perlu menangani atau melempar MalformedUrlException dan IOException.
Setelah itu, variabel koneksi akan menyimpan referensi ke objek HttpsUrlConnectionImpl. Secara default, permintaan GET akan dihasilkan. Untuk menambahkan Header, kami menggunakan metode
setRequestProperty () , yang menerima kunci dan nilai. Kita perlu menginstal Tipe-Konten di sini yang memiliki
aplikasi nilai
/ x-www-form-urlencoded . Baiklah, dan kami melakukannya!
connection.setRequestProperty(“Content-Type”, “application/x-www-form-urlencoded”);
Sekarang tinggal mengirim permintaan dengan menulis token kami dan membatasi ke tubuh. Untuk melakukan ini, setel bidang doOutput objek koneksi ke true menggunakan metode
setDoOutput () ;
connection.setDoOutput(true);
Selanjutnya, bagian yang paling menarik - Anda harus mengirimkan tubuh permintaan kami ke OutputStream. Kami akan menggunakan OutputStreamWriter:
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
Ada satu peringatan: setelah kita memanggil metode getOutputStream (), metode permintaan berubah menjadi POST, karena GET tidak menyediakan untuk tubuh permintaan, tetapi karena slack tidak memaksakan pembatasan ketat pada metode, semuanya baik-baik saja. Maka permintaan GET akan terlihat seperti ini:
GET /users.list?token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100 HTTP/1.1 Content-Type: application/x-www-form-urlencoded
Tetapi saya tidak mulai mengulanginya. Dan sebaliknya, permintaan kami ternyata seperti ini:
POST /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5
(* beberapa tajuk diatur oleh HttpsUrlConnection sendiri dan tidak ada di sini)
Jadi, untuk menulis tubuh permintaan kami, kami menggunakan write ();
String reqBody = “token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100”; writer.write(reqBody); writer.close();
Setelah itu, permintaan kami akan dikirim, dan kami dapat membaca tanggapan yang diterima. Penting untuk menutup OutputStream atau melakukan flush () sebelum menerima InputStream, jika tidak, data tidak akan meninggalkan buffer (atau, Anda dapat menggunakan PrintStream - dalam metode println (), flush () dipanggil secara default). Untuk membaca saya menggunakan BufferedReader:
StringBuilder respBody = new StringBuilder(); BufferedReader reader = new BufferedReader(connection.getInputStream()); reader.lines().forEach(l -> respBody.append(l + “\r\n”); reader.close();
(* gunakan baris () untuk mendapatkan Streaming pada output; \ r \ n - karakter CRLF - menyisipkan transisi ke baris baru)
Dan, jika kami berhasil mengotentikasi, variabel respBody harus menyimpan respons kami dari server, yang dalam kasus kami adalah objek JSON. Setelah itu, dapat dikirim ke tahap pemrosesan selanjutnya.
Setelah beberapa optimasi, semuanya terlihat seperti ini:
package main.java.com.bilichenko.learning; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import java.util.Optional; import java.util.stream.Collectors; public class SlackClient { private static final String HOST = "https://api.slack.com"; private static final String GET_USERS_URI = "/api/users.list"; private static final String TOKEN = "xx-ooo-YOUR-TOKEN-HERE"; public static void main(String[] args) throws IOException { SlackClient slackClient = new SlackClient(); System.out.println(slackClient.getRawResponse(HOST + GET_USERS_URI, "application/x-www-form-urlencoded", "token=" + TOKEN).orElse("no response")); } public Optional<String> getRawResponse(String url, String contentType, String requestBody) throws MalformedURLException, IOException { HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestProperty("Content-Type", contentType); connection.setConnectTimeout(10000); connection.setRequestMethod("POST"); connection.setDoOutput(true); try(OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream())) { writer.write(requestBody); } if (connection.getResponseCode() != 200) { System.err.println("connection failed"); return Optional.empty(); } try(BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream(), Charset.forName("utf-8")))) { return Optional.of(reader.lines().collect(Collectors.joining(System.lineSeparator()))); } } }
Semoga bermanfaat!