ترحيب
سأحاول اليوم التحدث عن كيفية إرسال طلب وقراءة الرد من خادم HTTP باستخدام URLConnection من مكتبة JRE.
نحن نتعلم حاليًا جافا عبر الإنترنت. يستخدم فريقنا بأكمله سلاك للعمل والتواصل. للحصول على معلومات حول المستخدمين ، نستخدم واجهة برمجة تطبيقات Slack. لكي لا نتحدث عن واجهة برمجة التطبيقات (API) نفسها لفترة طويلة (هذا موضوع لمقال منفصل) ، سأقول بإيجاز: واجهة برمجة تطبيقات Slack مبنية على بروتوكول HTTP ، للحصول على معلومات حول المستخدمين ، تحتاج إلى إرسال طلب مع واجهة مستخدم URI والتي يجب أن يكون فيها اسم طريقة من واجهة برمجة التطبيقات إلى عنوان المضيف
api. slack.com فيما يلي قائمة ببعض الطرق:
- users.list
- chat.postMessage
- conversations.create
- files.upload
- im.open
للحصول على قائمة المستخدمين ، فأنت بحاجة إلى طريقة users.list. نحن نشكل URI -
/api/users.list في نص الطلب ، يجب أن يكون هناك رمز مصادقة في نموذج الطلب / x-www-form-urlencoded ، أي أن الطلب يجب أن يبدو مثل هذا (ولكن هناك فارق بسيط واحد سيكون أقل):
GET /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5
كنت على دراية بمكتبة Apache HttpComponents ، ولكن لأغراض البحث ، سنستخدم الأدوات المتوفرة في مكتبة Java 8 القياسية ، أي تطبيق java.net.URLConnection.
للحصول على كيان URLConnection ، تحتاج إلى استخدام كائن فئة java.net.URL ، حيث يأخذ مُنشئه نوع السلسلة حيث ، بالإضافة إلى كل شيء ، يجب تحديد البروتوكول - في حالتنا ، https.
بعد تلقي كيان عنوان URL ، ندعو طريقة
openConnection () التي ستُرجع كيان HttpsUrlConnection.
String url = “https:
في هذه الحالة ، تحتاج إلى معالجة أو رمي MalformedUrlException و IOException.
بعد ذلك ، سيقوم متغير الاتصال بتخزين مرجع لكائن HttpsUrlConnectionImpl. افتراضيًا ، سيتم إنشاء طلب GET. لإضافة رأس ، نستخدم طريقة
setRequestProperty () التي تقبل المفتاح والقيمة. نحتاج إلى تثبيت Content-Type هنا والذي يحتوي على قيمة
application / x-www-form-urlencoded . حسنا ، ونحن نفعل ذلك!
connection.setRequestProperty(“Content-Type”, “application/x-www-form-urlencoded”);
الآن يبقى فقط إرسال طلب عن طريق كتابة الرمز المميز لدينا والحد في الجسم. للقيام بذلك ، قم بتعيين حقل doOutput الخاص بكائن الاتصال على true باستخدام طريقة
setDoOutput () ؛
connection.setDoOutput(true);
بعد ذلك ، الجزء الأكثر إثارة للاهتمام - تحتاج إلى تمرير نص طلبنا بطريقة أو بأخرى إلى OutputStream. سوف نستخدم OutputStreamWriter:
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
هناك تحذير واحد: بعد أن أطلقنا على أسلوب getOutputStream () ، تتغير طريقة الطلب إلى POST ، حيث إن GET لا يوفر نص الطلب ، ولكن الفائدة هي أن الركود لا يضع قيودًا صارمة على الطريقة ، لذلك كان كل شيء جيدًا. ولذا يجب أن يبدو طلب GET كما يلي:
GET /users.list?token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100 HTTP/1.1 Content-Type: application/x-www-form-urlencoded
لكنني لم أبدأ في إعادته. وبدلاً من ذلك ، تحول طلبنا كما يلي:
POST /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5
(* يتم تعيين بعض الرؤوس بواسطة HttpsUrlConnection أنفسهم وهم غائبون هنا)
وهكذا ، لكتابة نص طلبنا ، نستخدم كتابة () ؛.
String reqBody = “token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100”; writer.write(reqBody); writer.close();
بعد ذلك ، سيتم إرسال طلبنا ، ويمكننا قراءة الرد المستلم. من المهم إغلاق OutputStream أو القيام flush () قبل استلام InputStream ، وإلا فلن تترك البيانات المخزن المؤقت (بدلاً من ذلك ، يمكنك استخدام PrintStream - في طريقة println () ، يتم استدعاء flush () افتراضيًا). لقراءة اعتدت BufferedReader:
StringBuilder respBody = new StringBuilder(); BufferedReader reader = new BufferedReader(connection.getInputStream()); reader.lines().forEach(l -> respBody.append(l + “\r\n”); reader.close();
(* استخدم السطور () للحصول على الدفق عند الإخراج ؛ \ r \ n - حرف CRLF - يدرج الانتقال إلى سطر جديد)
وإذا نجحنا في المصادقة ، فيجب على متغير respBody تخزين ردنا من الخادم ، وهو في حالتنا كائن JSON. بعد ذلك ، يمكن إرسالها إلى المرحلة التالية من المعالجة.
بعد بعض التحسين ، يبدو كل شيء كما يلي:
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()))); } } }
آمل أن تكون مفيدة!