חקר לקוח ה- HTTP החדש בג'אווה

1. הקדמה

במדריך זה נחקור את הדגירה החדשה של Java 9 HttpClient.

עד לאחרונה, ג'אווה סיפקה רק את חיבור HttpURLC API - שהוא ברמה נמוכה ואינו ידוע כעשיר בתכונותוידידותי למשתמש.

לכן, נעשה שימוש נפוץ בכמה ספריות צד שלישי - כגון Apache HttpClient, Jetty ו- RestTemplate של Spring.

2. הגדרה ראשונית

מודול לקוח HTTP מקובץ כמודול חממה ב- JDK 9 ותומך ב- HTTP / 2 עם תאימות לאחור שעדיין מקלה על HTTP / 1.1.

כדי להשתמש בו, עלינו להגדיר את המודול שלנו באמצעות a module-info.java קובץ המציין גם את המודול הנדרש להפעלת היישום שלנו:

מודול com.baeldung.java9.httpclient {דורש jdk.incubator.httpclient; }

3. סקירת API של לקוח HTTP

בניגוד HttpURL חיבור, לקוח HTTP מספק מנגנוני בקשה סינכרוניים ואסינכרוניים.

ה- API מורכב משלוש מחלקות ליבה:

  • HttpRequestמייצג את הבקשה להישלח באמצעות HttpClient
  • HttpClientמתנהג כמכולה למידע תצורה המשותף למספר בקשות
  • HttpResponseמייצג את התוצאה של HttpRequest שִׂיחָה

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

4. HttpRequest

Http בקשה, כשם מציע, הוא אובייקט המייצג בקשה שאנו רוצים לשלוח. ניתן ליצור מקרים חדשים באמצעות HttpRequest.Builder.

אנחנו יכולים להשיג את זה על ידי התקשרות HttpRequest.newBuilder (). בּוֹנֶה מחלקה מספקת שורת שיטות בהן אנו יכולים להשתמש כדי להגדיר את בקשתנו.

נסקור את החשובים ביותר.

4.1. הגדרה URI

הדבר הראשון שעלינו לעשות בעת יצירת בקשה הוא לספק את כתובת ה- URL.

אנו יכולים לעשות זאת בשתי דרכים - באמצעות הקונסטרוקטור עבור בּוֹנֶה עם URI פרמטר או בשיטת קריאה uri (URI) על בּוֹנֶה למשל:

HttpRequest.newBuilder (URI חדש ("// postman-echo.com/get")) HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/get"))

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

4.2. ציון שיטת HTTP

אנו יכולים להגדיר את שיטת ה- HTTP בה תשתמש בקשתנו על ידי קריאה לאחת מהשיטות ממנה בּוֹנֶה:

  • לקבל()
  • POST (גוף BodyProcessor)
  • PUT (BodyProcessor body)
  • מחק (גוף BodyProcessor)

נכסה BodyProcessor בפירוט, בהמשך. עכשיו, בואו פשוט ניצור דוגמה פשוטה מאוד לבקשה של GET:

HttpRequest בקשה = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/get")). GET () .build ();

לבקשה זו יש את כל הפרמטרים הנדרשים על ידי HttpClient. עם זאת, לעיתים עלינו להוסיף פרמטרים נוספים לבקשתנו; להלן כמה חשובים:

  • הגרסה של פרוטוקול HTTP
  • כותרות
  • פסק זמן

4.3. הגדרת גרסת פרוטוקול HTTP

ה- API ממנף באופן מלא את פרוטוקול HTTP / 2 ומשתמש בו כברירת מחדל, אך אנו יכולים להגדיר באיזו גרסת הפרוטוקול אנו רוצים להשתמש.

HttpRequest בקשה = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/get")) .version (HttpClient.Version.HTTP_2) .GET () .build ();

חשוב להזכיר כאן הוא שהלקוח יחזור ל-, למשל, HTTP / 1.1 אם HTTP / 2 אינו נתמך.

4.4. הגדרת כותרות

במקרה שנרצה להוסיף כותרות נוספות לבקשתנו, נוכל להשתמש בשיטות הבונה המסופקות.

אנו יכולים לעשות זאת באחת משתי דרכים:

  • העברת כל הכותרות כצמדי ערך מפתח אל ה- כותרות () שיטה או לפי
  • באמצעות כּוֹתֶרֶת() שיטה לכותרת ערך מפתח יחיד:
HttpRequest בקשה = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/get")). כותרות ("key1", "value1", "key2", "value2"). GET () .לִבנוֹת(); HttpRequest request2 = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/get")). כותרת ("key1", "value1"). Header ("key2", "value2"). GET () .build (); 

השיטה השימושית האחרונה בה אנו יכולים להשתמש בהתאמה אישית של בקשתנו היא פסק זמן ().

4.5. קביעת פסק זמן

בואו נגדיר את משך הזמן שאנו רוצים לחכות לתגובה.

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

ניתן לקבוע את פסק הזמן עם מֶשֶׁך אובייקט - בשיטת קריאה פסק זמן() במקרה של הקבלן:

HttpRequest בקשה = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/get")). Timeout (Duration.of (10, SECONDS)) .GET () .build ();

5. קביעת גוף בקשה

אנו יכולים להוסיף גוף לבקשה באמצעות שיטות בניית הבקשות: POST (גוף BodyProcessor), PUT (BodyProcessor body) ו מחק (גוף BodyProcessor).

ה- API החדש מספק מספר BodyProcessor יישומים מחוץ לקופסה שמפשטים את העברת גוף הבקשה:

  • StringProcessor (קורא גוף מתוך א חוּט, נוצר עם HttpRequest.BodyProcessor.fromString)
  • InputStreamProcessor (קורא גוף מתוך InputStream, נוצר עם HttpRequest.BodyProcessor.fromInputStream)
  • ByteArrayProcessor (קורא גוף ממערך בתים, נוצר עם HttpRequest.BodyProcessor.fromByteArray)
  • מעבד קבצים (קורא גוף מתוך קובץ בנתיב הנתון, נוצר עם HttpRequest.BodyProcessor.fromFile)

במקרה שאיננו זקוקים לגוף, נוכל פשוט לעבור בתוך HttpRequest.noBody ():

HttpRequest בקשה = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/post")). POST (HttpRequest.noBody ()) .build ();

5.1. StringBodyProcessor

הגדרת גוף בקשה עם כל אחד BodyProcessor היישום מאוד פשוט ואינטואיטיבי.

לדוגמא, אם אנו רוצים להעביר פשוט חוּט כגוף, אנו יכולים להשתמש בו StringBodyProcessor.

כפי שכבר הזכרנו, ניתן ליצור אובייקט זה בשיטת מפעל fromString (); זה לוקח רק א חוּט אובייקט כוויכוח ויוצר ממנו גוף:

בקשת HttpRequest = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/post")). כותרות ("סוג תוכן", "טקסט / רגיל; טקסט = UTF-8"). POST (HttpRequest.BodyProcessor.fromString ("גוף בקשת לדוגמא")) .build (); 

5.2. InputStreamBodyProcessor

לשם כך, ה InputStream צריך לעבור כ- ספק (כדי להפוך את יצירתו לעצלנית), כך שהיא שונה מעט מהמתואר לעיל StringBodyProcessor.

עם זאת, זה גם די פשוט:

בייט [] sampleData = "גוף בקשת לדוגמא" .getBytes (); בקשת HttpRequest = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/post")). כותרות ("סוג תוכן", "טקסט / רגיל; טקסט = UTF-8"). POST (HttpRequest.BodyProcessor .fromInputStream (() -> ByteArrayInputStream חדש (sampleData))) .build (); 

שימו לב כיצד השתמשנו בפשוטה ByteArrayInputStream פה; זה יכול, כמובן, להיות כלשהו InputStream יישום.

5.3. ByteArrayProcessor

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

בייט [] sampleData = "גוף בקשת לדוגמא" .getBytes (); בקשה HttpRequest = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/post")). כותרות ("סוג תוכן", "טקסט / רגיל; טקסט = UTF-8"). POST (HttpRequest.BodyProcessor.fromByteArray (sampleData)) .build ();

5.4. מעבד קבצים

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

בקשה HttpRequest = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/post")). כותרות ("סוג תוכן", "טקסט / רגיל; טקסט = UTF-8"). POST (HttpRequest.BodyProcessor.fromFile (Paths.get ("src / test / resources / sample.txt"))) .build ();

סקרנו כיצד ליצור HttpRequest וכיצד להגדיר בו פרמטרים נוספים.

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

6. HttpClient

כל הבקשות נשלחות באמצעות HttpClient אשר ניתן לאינסטנטציה באמצעות HttpClient.newBuilder () שיטה או על ידי התקשרות HttpClient.newHttpClient ().

הוא מספק הרבה שיטות שימושיות ותיאור עצמי בו אנו יכולים להשתמש בכדי לטפל בבקשתנו / תשובתנו.

בואו נסקור כמה מאלה כאן.

6.1. הגדרת פרוקסי

אנו יכולים להגדיר פרוקסי לחיבור. פשוט תתקשרו פרוקסי () שיטה על א בּוֹנֶה למשל:

תגובה HttpResponse = HttpClient .newBuilder (). Proxy (ProxySelector.getDefault ()) .build (). לשלוח (בקשה, HttpResponse.BodyHandler.asString ()); 

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

6.2. קביעת מדיניות ההפניה מחדש

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

במקרה זה נקבל קוד מצב HTTP 3xx, בדרך כלל עם המידע על URI חדש. HttpClient יכול להפנות את הבקשה ל- URI החדש באופן אוטומטי אם אנו קובעים את מדיניות ההפניה המתאימה.

אנחנו יכולים לעשות את זה עם followRedirects () שיטה ב בּוֹנֶה:

תגובה HttpResponse = HttpClient.newBuilder () .followRedirects (HttpClient.Redirect.ALWAYS) .build (). לשלוח (בקשה, HttpResponse.BodyHandler.asString ());

כל המדיניות מוגדרת ומתוארת ב- enum HttpClient.Redirect.

6.3. הגדרה מאמת לחיבור

An מאמת הוא אובייקט שמנהל משא ומתן על אישורים (אימות HTTP) עבור חיבור.

הוא מספק תוכניות אימות שונות (כמו למשל אימות בסיסי או עיכול). ברוב המקרים, אימות דורש שם משתמש וסיסמה כדי להתחבר לשרת.

אנחנו יכולים להשתמש אימות סיסמה מעמד שהוא רק בעל הערכים הבאים:

תגובה HttpResponse = HttpClient.newBuilder () .authenticator (מאמת חדש () {@Override מוגן PasswordAuthentication getPasswordAuthentication () {להחזיר PasswordAuthentication חדש ("שם משתמש", "סיסמה" .toCharArray ());}}). לבנות (). לשלוח (בקשה, HttpResponse.BodyHandler.asString ());

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

שים לב שלא על כל בקשה להשתמש באותו שם משתמש וסיסמה. ה מאמת הכיתה מספקת מספר getXXX (לְמָשָׁל., getRequestingSite ()) שיטות בהן ניתן להשתמש כדי לגלות אילו ערכים יש לספק.

עכשיו נבחן את אחת התכונות השימושיות ביותר של חדש HttpClient - שיחות אסינכרוניות לשרת.

6.4. שלח בקשות - סנכרון מול אסינכרון

HttpClient החדש מספק שתי אפשרויות למשלוח בקשה לשרת:

  • לִשְׁלוֹחַ(…) - באופן סינכרוני (חוסם עד שמגיעה התגובה)
  • sendAsync (...) - באופן אסינכרוני (לא מחכה לתגובה, לא חוסם)

עד עכשיו, לִשְׁלוֹחַ(...) שיטה ממתינה באופן טבעי לתגובה:

תגובה HttpResponse = HttpClient.newBuilder () .build (). לשלוח (בקשה, HttpResponse.BodyHandler.asString ()); 

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

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

אז, עכשיו, אנחנו יכולים להשתמש sendAsync (...) שיטת - המחזירה CompleteFeatureלעבד בקשה בצורה אסינכרונית:

העתיד תגובה = HttpClient.newBuilder () .build () .sendAsync (בקשה, HttpResponse.BodyHandler.asString ());

ה- API החדש יכול גם להתמודד עם תגובות מרובות, ולהזרם את גופי הבקשה והתגובה:

יעדי רשימה = Arrays.asList (URI חדש ("// postman-echo.com/get?foo1=bar1"), URI חדש ("// postman-echo.com/get?foo2=bar2")); לקוח HttpClient = HttpClient.newHttpClient (); רשימה עתיד = target.stream () .map (target -> client .sendAsync (HttpRequest.newBuilder (target). GET (). build (), HttpResponse.BodyHandler.asString ()). ואז החל (תגובה -> תגובה.גוף ( (Collectors.toList ());

6.5. הגדרה מוציא להורג לשיחות אסינכרוניות

אנחנו יכולים גם להגדיר מוציא להורג המספק אשכולות לשימוש שיחות אסינכרוניות.

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

ExecutorService executorService = Executors.newFixedThreadPool (2); העתיד response1 = HttpClient.newBuilder () .executor (executorService) .build () .sendAsync (בקשה, HttpResponse.BodyHandler.asString ()); העתיד response2 = HttpClient.newBuilder () .executor (executorService) .build () .sendAsync (בקשה, HttpResponse.BodyHandler.asString ());

כברירת מחדל, ה- HttpClient משתמש בביצוע java.util.concurrent.Executors.newCachedThreadPool ().

6.6. הגדרת א CookieManager

עם ממשק API ובונה חדשים, פשוט להגדיר CookieManager לחיבור שלנו. אנו יכולים להשתמש בשיטת הבנאי cookieManager (CookieManager cookieManager) כדי להגדיר לקוח ספציפי CookieManager.

בואו, למשל, נגדיר CookieManager מה שלא מאפשר כלל לקבל עוגיות:

HttpClient.newBuilder () .cookieManager (CookieManager חדש (null, CookiePolicy.ACCEPT_NONE)) .build (); 

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

httpClient.cookieManager (). get (). getCookieStore () 

עכשיו נתמקד במחלקה האחרונה מ- Http API - ה- HttpResponse.

7. HttpResponse לְהִתְנַגֵד

ה HttpResponse class מייצג את התגובה מהשרת. הוא מספק מספר שיטות שימושיות - אך שתיים החשובות ביותר הן:

  • statusCode () - מחזיר קוד מצב (סוג int) לתגובה (חיבור HttpURLC הכיתה מכילה ערכים אפשריים)
  • גוּף() - מחזיר גוף לתגובה (סוג ההחזרה תלוי בתגובה BodyHandler הפרמטר הועבר ל לִשְׁלוֹחַ() שיטה)

לאובייקט התגובה יש שיטה שימושית אחרת אותה נסקור כמו אורי (), כותרות (), נגררים () ו גִרְסָה().

7.1. URI של אובייקט התגובה

השיטה אורי () על אובייקט התגובה מחזירה את URI ממנו קיבלנו את התגובה.

לפעמים זה יכול להיות שונה מ URI באובייקט הבקשה מכיוון שעלולה להופיע הפניה מחדש:

assertThat (request.uri () .toString (), equalTo ("// stackoverflow.com")); assertThat (response.uri () .toString (), equalTo ("// stackoverflow.com/"));

7.2. כותרות מתגובה

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

תגובה HttpResponse = HttpClient.newHttpClient (). לשלוח (בקשה, HttpResponse.BodyHandler.asString ()); HttpHeaders responseHeaders = response.headers ();

זה חוזר HttpHeaders אובייקט כסוג החזרה. זהו סוג חדש שהוגדר ב jdk.incubator.http חבילה המייצגת תצוגה לקריאה בלבד של כותרות HTTP.

יש לו כמה שיטות שימושיות שמפשטות את החיפוש אחר ערך כותרות.

7.3. קבל טריילרים מתגובה

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

אנו יכולים להשיג אותם בשיטת קריאה נגררים () עַל Http תגובה:

תגובה HttpResponse = HttpClient.newHttpClient (). לשלוח (בקשה, HttpResponse.BodyHandler.asString ()); קדימונים CompletableFuture = response.trailers (); 

ציין זאת נגררים () השיטה מחזירה העתיד לְהִתְנַגֵד.

7.4. גרסת התגובה

השיטה גִרְסָה() מגדיר איזו גרסה של פרוטוקול HTTP שימשה לשיחה עם שרת.

זכרו, שגם אם נגדיר שאנחנו רוצים להשתמש ב- HTTP / 2, השרת יכול לענות באמצעות HTTP / 1.1.

הגרסה עליה ענה השרת מוגדרת בתגובה:

HttpRequest בקשה = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/get")) .version (HttpClient.Version.HTTP_2) .GET () .build (); תגובה HttpResponse = HttpClient.newHttpClient (). לשלוח (בקשה, HttpResponse.BodyHandler.asString ()); assertThat (response.version (), equalTo (HttpClient.Version.HTTP_1_1));

8. לקוח Java 11 Http

השינוי העיקרי בג'אווה 11 היה הסטנדרטיזציה של ממשק API של לקוח HTTP המיישם HTTP / 2 ושקע אינטרנט. מטרתו להחליף את המורשת HttpUrlConnection בכיתה שנמצאת ב- JDK מאז השנים הראשונות של Java.

השינוי יושם כחלק מ- JEP 321.

8.1. שינויים גדולים כחלק מ- JEP 321

  1. ממשק ה- API של ה- HTTP המודגרות מג'אווה 9 שולב כעת באופן רשמי ב- API של Java SE. ניתן למצוא את ממשקי ה- API החדשים של HTTP ב java.net. HTTP. *
  2. הגרסה החדשה יותר של פרוטוקול HTTP נועדה לשפר את הביצועים הכוללים של שליחת בקשות על ידי לקוח וקבלת תגובות מהשרת. זה מושג על ידי הכנסת מספר שינויים כגון ריבוב זרמים, דחיסת כותרת והבטחות דחיפה.
  3. נכון ל- Java 11, ה- API כעת אסינכרוני לחלוטין (היישום הקודם של HTTP / 1.1 נחסם). שיחות אסינכרוניות מיושמות באמצעות העתידהעתיד היישום דואג ליישם כל שלב לאחר סיום הקודם, כך שכל הזרימה הזו היא א-סינכרונית.
  4. ה- API החדש של לקוח HTTP מספק דרך סטנדרטית לבצע פעולות רשת HTTP עם תמיכה בתכונות אינטרנט מודרניות כגון HTTP / 2, ללא צורך להוסיף תלות של צד שלישי.
  5. ממשקי ה- API החדשים מספקים תמיכה מקורית ב- HTTP 1.1 / 2 WebSocket. שיעורי הליבה והממשק המספקים את פונקציונליות הליבה כוללים:
  • ה מחלקה HttpClient, java.net.http.HttpClient
  • ה HttpRequest מעמד, java.net.http.HttpRequest
  • ה HttpResponse מִמְשָׁק, java.net.http.HttpResponse
  • ה WebSocket מִמְשָׁק, java.net.http.WebSocket

8.2. בעיות עם לקוח ה- HTTP טרום Java 11

הקיימת חיבור HttpURLC ל- API ולהטמעתו היו בעיות רבות:

  • ממשק ה- API של URLConnection תוכנן עם מספר פרוטוקולים שאינם פועלים כעת (FTP, גופר וכו ').
  • ה- API מקדים HTTP / 1.1 והוא מופשט מדי.
  • זה עובד במצב חסימה בלבד (כלומר, שרשור אחד לכל בקשה / תגובה).
  • קשה מאוד לשמור עליו.

9. שינויים בלקוח Http עם Java 11

9.1. הצגת כיתות מפעל סטטיות

שיעורי מפעל סטטיים חדשים BodyPublishers, מנויי Body, ו BodyHandlers מוצגות הכוללות יישומים קיימים של BodyPublisher, BodySubscriber ו BodyHandler.

אלה משמשים לביצוע משימות נפוצות שימושיות, כגון טיפול בגוף התגובה כמחרוזת או הזרמת הגוף לקובץ.

עבור למשל בקדם ג'אווה 11 היינו צריכים לעשות משהו כזה:

תגובה HttpResponse = client.send (בקשה, HttpResponse.BodyHandler.asString ());

שאנו יכולים לפשט כעת כ:

תגובה HttpResponse = client.send (בקשה, BodyHandlers.ofString ());

כמו כן, שמם של השיטות הסטטיות תוקן לבהירות רבה יותר.

עבור למשל שיטות שמות כמו fromXxx משמשים כאשר אנו משתמשים בהם כמתאמים או שמות כמו ofXxx כאשר אנו יוצרים מטפלים / מנויים שהוגדרו מראש.

9.2. שיטות שוטפות לסוגי גוף נפוצים

הוצגו שיטות מפעל נוחות למו"לים ומטפלים שנוצרו לטיפול בסוגי גוף נפוצים.

עבור למשל יש לנו להלן שיטות שוטפות ליצירת מפרסמים מבתים, קבצים ומחרוזות:

BodyPublishers.ofByteArray BodyPublishers.ofFile BodyPublishers.ofString

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

BodyHandlers.ofByteArray BodyHandlers.ofString BodyHandlers.ofFile

9.3. שינויים אחרים ב- API

1. עם ה- API החדש הזה, נשתמש BodyHandlers. מחיקה () ו BodyHandlers.replacement (ערך) במקום מחק (החלפת אובייקט):

HttpResponse response1 = HttpClient.newHttpClient (). לשלוח (בקשה, BodyHandlers.discarding ());
HttpResponse response1 = HttpClient.newHttpClient (). לשלוח (בקשה, BodyHandlers.replacing (ערך));

2. שיטה חדשה ofLines () ב BodyHandlers נוסף לטיפול בכדי להזרים את גוף התגובה כזרם של קווים.

3. מ- LineSubscriber מתווספת שיטה ב BodyHandlers class שיכול לשמש כמתאם בין a BodySubscriber ומבוסס טקסט זרימה. מנוי המנתח טקסט שורה אחר שורה.

4. נוסף חדש מיפוי BodySubscriber ב מנויי BodyS מחלקה שיכולה לשמש למיפוי מסוג גוף תגובה אחד למשנהו על ידי החלת הפונקציה הנתונה על אובייקט הגוף.

5. ב HttpClient.Redirect, קבועי אנום SAME_PROTOCOL ו לבטח המדיניות מוחלפת באולם חדש נוֹרמָלִי.

10. טיפול בהבטחות דחיפה ב- HTTP / 2

לקוח Http חדש תומך בהבטחות דחיפה PushPromiseHandler מִמְשָׁק.

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

זו באמת תכונת הריבוב של HTTP / 2 שמאפשרת לנו לשכוח מאגד משאבים. עבור כל משאב, השרת שולח בקשה מיוחדת, המכונה הבטחת דחיפה ללקוח.

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

ה HttpClient יש עומס יתר sendAsync שיטה המאפשרת לנו להתמודד עם הבטחות כאלה, כפי שמוצג בדוגמה הבאה.

בואו ניצור תחילה a PushPromiseHandler:

פרטי סטטי PushPromiseHandler pushPromiseHandler () {return (HttpRequest initiatingRequest, HttpRequest pushPromiseRequest, Function> acceptor) -> {acceptor.apply (BodyHandlers.ofString ()) .thenAccept (resp -> {System.out.println ("תגובה דחופה:" + resp.uri () + ", כותרות:" + resp. headers ());}); System.out.println ("בקשת הבטחה:" + pushPromiseRequest.uri ()); System.out.println ("בקשת הבטחה:" + pushPromiseRequest.headers ()); }; }

הבא, בואו נשתמש sendAsync שיטה להתמודד עם הבטחת הדחיפה הזו:

httpClient.sendAsync (pageRequest, BodyHandlers.ofString (), pushPromiseHandler ()) .thenAccept (pageResponse -> {System.out.println ("קוד מצב תגובה לתגובה:" + pageResponse.statusCode ()); System.out.println ( "כותרות תגובה לדף:" + pageResponse.headers ()); מחרוזת responseBody = pageResponse.body (); System.out.println (responseBody);}) .join (); 

11. מסקנה

במאמר זה בחנו את Java 9 HttpClient ממשק API המספק גמישות רבה ותכונות חזקות. הקוד השלם המשמש ל- HttpClient API של Java 9 זמין ב- GitHub.

בדקנו גם את השינוי החדש ב- Java 11 HttpClient, שתקנן את ה- HttpClient המדגירה שהוצג ב- Java 9 עם שינויים חזקים יותר. קטעי הקוד המשמשים עבור לקוח Java 11 Http זמינים גם ב- Github.

הערה: בדוגמאות השתמשנו בנקודות קצה של REST לדוגמה שניתנו על ידי // פוסטמן-echo.com.