בצע בקשת HTTP פשוטה בג'אווה

1. סקירה כללית

במדריך מהיר זה אנו מציגים א דרך לבצע בקשות HTTP בג'אווה - באמצעות מחלקת Java המובנית HttpUrlConnection.

שים לב כי החל מ- JDK 11, Java מספקת API חדש לביצוע בקשות HTTP, אשר נועד כתחליף ל- HttpUrlConnection, ה HttpClient ממשק API.

2. HttpUrlConnection

ה HttpUrlConnection הכיתה מאפשרת לנו לבצע בקשות HTTP בסיסיות ללא שימוש בספריות נוספות. כל השיעורים שאנחנו צריכים הם חלק מהשיעורים java.net חֲבִילָה.

החסרונות בשימוש בשיטה זו הם בכך הקוד יכול להיות מסורבל יותר מספריות HTTP אחרות וכי הוא אינו מספק פונקציות מתקדמות יותר כגון שיטות ייעודיות להוספת כותרות או אימות.

3. יצירת בקשה

אנחנו יכולים ליצור HttpUrlConnection למשל באמצעות openConnection () שיטת ה- כתובת אתר מעמד. שים לב ששיטה זו יוצרת רק אובייקט חיבור אך עדיין לא מקימה את החיבור.

ה HttpUrlConnection class משמש לכל סוגי הבקשות על ידי הגדרת ה- בקשת שיטה תכונה לאחד הערכים: GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.

בואו ליצור חיבור לכתובת URL נתונה בשיטת GET:

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

4. הוספת פרמטרים של בקשה

אם אנו רוצים להוסיף פרמטרים לבקשה, עלינו להגדיר את doOutput נכס ל נָכוֹןואז כתוב a חוּט של הטופס param1 = ערך¶m2 = ערך אל ה OutputStream של ה HttpUrlConnection למשל:

פרמטרים של מפה = HashMap חדש (); parameters.put ("param1", "val"); con.setDoOutput (נכון); DataOutputStream out = DataOutputStream חדש (con.getOutputStream ()); out.writeBytes (ParameterStringBuilder.getParamsString (פרמטרים)); out.flush (); out.close ();

כדי להקל על השינוי של פרמטר מפה, כתבנו מחלקת שירות בשם ParameterStringBuilder המכיל שיטה סטטית, getParamsString (), שהופך א מַפָּה לתוך חוּט בפורמט הנדרש:

מחלקה ציבורית ParameterStringBuilder {מחרוזת סטטית ציבורית getParamsString (Params Map) זורק UnsupportedEncodingException {StringBuilder result = new StringBuilder (); עבור (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 ("&"); } מחרוזת resultString = result.toString (); return resultString.length ()> 0? resultString.substring (0, resultString.length () - 1): resultString; }}

5. הגדרת כותרות בקשה

ניתן להשיג הוספת כותרות לבקשה באמצעות ה- setRequestProperty () שיטה:

con.setRequestProperty ("סוג תוכן", "יישום / json");

כדי לקרוא את הערך של כותרת מחיבור, אנו יכולים להשתמש ב- getHeaderField () שיטה:

מחרוזת contentType = con.getHeaderField ("סוג תוכן");

6. קביעת תצורה של פסק זמן

HttpUrlConnection הכיתה מאפשרת הגדרת פסק הזמן לחיבור ולקריאה. ערכים אלה מגדירים את מרווח הזמן להמתין לקמת החיבור לשרת או שיהיו נתונים זמינים לקריאה.

כדי להגדיר את ערכי הזמן הקצוב, נוכל להשתמש ב- setConnectTimeout () ו setReadTimeout () שיטות:

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

בדוגמה, הגדרנו את שני ערכי הזמן הקצוב לחמש שניות.

7. טיפול בעוגיות

ה java.net החבילה מכילה שיעורים שמקלים על עבודה עם עוגיות כגון CookieManager ו HttpCookie.

ראשית, ל קרא את העוגיות מתגובה, אנו יכולים לאחזר את הערך של ה- סט-קוקי כותרת ונתח אותה לרשימה של HttpCookie חפצים:

מחרוזת cookiesHeader = con.getHeaderField ("Set-Cookie"); רשימת עוגיות = HttpCookie.parse (cookiesHeader);

הבא, אנחנו נעשה הוסף את העוגיות לחנות העוגיות:

cookies.forEach (cookie -> cookieManager.getCookieStore (). הוסף (null, cookie));

בואו נבדוק אם עוגיה התקשרה שם משתמש קיים, ואם לא, נוסיף אותו לחנות העוגיות עם הערך "ג'ון":

UsernameCookie אופציונלי = cookies.stream () .findAny (). פילטר (cookie -> cookie.getName (). שווה ("שם משתמש")); אם (usernameCookie == null) {cookieManager.getCookieStore (). הוסף (null, HttpCookie חדש ("שם משתמש", "ג'ון")); }

לבסוף, ל הוסף את העוגיות לבקשה, אנחנו צריכים להגדיר את עוגייה כותרת, לאחר סגירת החיבור ופתיחתו מחדש:

con. לנתק (); con = (HttpURLConnection) url.openConnection (); con.setRequestProperty ("Cookie", StringUtils.join (cookieManager.getCookieStore (). getCookies (), ";"));

8. טיפול בהפניות מחדש

אנחנו יכולים הפעל או השבת באופן אוטומטי בעקבות הפניות מחדש לחיבור ספציפי באמצעות setInstanceFollowRedirects () שיטה עם נָכוֹן אוֹ שֶׁקֶר פָּרָמֶטֶר:

con.setInstanceFollowRedirects (שקר);

אפשר גם הפעל או השבת הפניה אוטומטית לכל החיבורים:

HttpUrlConnection.setFollowRedirects (false);

כברירת מחדל, ההתנהגות מופעלת.

כאשר בקשה מחזירה קוד סטטוס 301 או 302, המציין הפניה מחדש, אנו יכולים לאחזר את ה- מקום כותרת וליצור בקשה חדשה לכתובת האתר החדשה:

אם (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM) {מיקום מחרוזת = con.getHeaderField ("מיקום"); URL newUrl = URL חדש (מיקום); con = (HttpURLConnection) newUrl.openConnection (); }

9. קריאת התגובה

קריאת תגובת הבקשה יכולה להיעשות על ידי מנתח את InputStream של ה HttpUrlConnection למשל.

כדי לבצע את הבקשה, אנו יכולים להשתמש ב- getResponseCode (), לְחַבֵּר(), getInputStream () אוֹ getOutputStream () שיטות:

int status = con.getResponseCode ();

לבסוף, בואו לקרוא את תגובת הבקשה ולהניח אותה בתא תוֹכֶן חוּט:

BufferedReader in = BufferedReader חדש (InputStreamReader חדש (con.getInputStream ())); מחרוזת inputLine; StringBuffer content = new StringBuffer (); בעוד ((inputLine = in.readLine ())! = null) {content.append (inputLine); } בקרוב();

ל סגור את החיבור, אנחנו יכולים להשתמש ב- לְנַתֵק() שיטה:

con. לנתק (); 

10. קריאת התגובה לבקשות שנכשלו

אם הבקשה נכשלה, מנסה לקרוא את InputStream של ה HttpUrlConnection מופע לא יעבוד. במקום זאת, אנחנו יכולים לצרוך את הזרם שמספק HttpUrlConnection.getErrorStream ().

אנחנו יכולים להחליט איזה InputStream לשימוש על ידי השוואת קוד מצב HTTP:

int status = con.getResponseCode (); קורא streamReader = null; אם (סטטוס> 299) {streamReader = InputStreamReader חדש (con.getErrorStream ()); } אחר {streamReader = InputStreamReader חדש (con.getInputStream ()); }

ולבסוף, אנו יכולים לקרוא את streamReader באותו אופן כמו הסעיף הקודם.

11. בניית התגובה המלאה

לא ניתן לקבל את ייצוג התגובה המלא באמצעות ה- HttpUrlConnection למשל.

למרות זאת, אנו יכולים לבנות אותו באמצעות כמה מהשיטות ש- HttpUrlConnection הצעות למשל:

מחלקה ציבורית FullResponseBuilder {מחרוזת סטטית ציבורית getFullResponse (HttpURLConnection con) זורק IOException {StringBuilder fullResponseBuilder = StringBuilder חדש (); // סטטוס קריאה והודעה // כותרות קריאה // קריאת תוכן התגובה fullResponseBuilder.toString (); }}

כאן אנו קוראים את חלקי התגובות, כולל קוד הסטטוס, הודעת הסטטוס והכותרות, ומוסיפים אותם לא StringBuilder למשל.

ראשית, בואו נוסיף את המידע על סטטוס התגובה:

fullResponseBuilder.append (con.getResponseCode ()) .append ("") .append (con.getResponseMessage ()) .append ("\ n");

לאחר מכן, נקבל את הכותרות באמצעות getHeaderFields () והוסף כל אחד מהם לשלנו StringBuilder בפורמט כותרת שם: HeaderValues:

con.getHeaderFields (). entrySet (). stream () .filter (entry -> entry.getKey ()! = null) .forEach (entry -> {fullResponseBuilder.append (entry.getKey ()). append (": "); רשימה 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");});

לבסוף נקרא את תוכן התגובה כפי שעשינו בעבר ולצרף אותו.

שים לב שה- getFullResponse השיטה תאמת אם הבקשה הצליחה או לא על מנת להחליט אם עליה להשתמש con.getInputStream () אוֹ con.getErrorStream () כדי לאחזר את תוכן הבקשה.

12. מסקנה

במאמר זה הראינו כיצד אנו יכולים לבצע בקשות HTTP באמצעות ה- HttpUrlConnection מעמד.

קוד המקור המלא של הדוגמאות ניתן למצוא באתר GitHub.