ספריית HTTP דלק עם Kotlin

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

במדריך זה, נסתכל על ספריית ה- Fuel HTTP, שהיא, לדברי דברי המחבר, ספריית הרשת HTTP הקלה ביותר עבור Kotlin / Android. יתר על כן, ניתן להשתמש בספרייה גם ב- Java.

המאפיינים העיקריים של הספרייה כוללים:

  • תמיכה בפעלים HTTP בסיסיים (GET, POST, DELETE וכו ') הן בקשות אסינכרוניות והן בקשות חסימה
  • יכולת להוריד ולהעלות קובץ (נתונים מרובי חלקים / טפסים)
  • אפשרות לנהל תצורה גלובלית
  • מודולי סידור אובייקטים מובנים (ג'קסון, Gson, Mhosi, Forge)
  • תמיכה במודול קורוטינים של Kotlin ו- RxJava 2.x
  • הגדר בקלות תבנית עיצוב נתב

2. תלות

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

  • מודול לתמיכה ב- Corxines של RxJava ו- Kotlin
  • מודול לתמיכה ברכיבי אדריכלות של Android ו- Android LiveData
  • ארבעה מודולים מהם נוכל לבחור את מודול סדרת האובייקטים לשימוש - Gson, Jackson, Moshi או Forge.

במדריך זה נתמקד במודול הליבה, במודולים עבור Coroutines, RxJava ומודול הסידור של Gson:

 com.github.kittinunf.fuel fuel $ {fuel.version} com.github.kittinunf.fuel fuel-gson $ {fuel.version} com.github.kittinunf.fuel fuel-rxjava $ {fuel.version} com.github. kittinunf.fuel fuel-coroutines $ {fuel.version} 

תוכל למצוא את הגרסאות העדכניות ביותר באתר JFrog Bintray.

3. הגשת בקשות

כדי להגיש בקשה, דלק מספק א חוּט סיומת. בנוסף וכחלופה, אנו יכולים להשתמש ב- דלק מחלקה שיש לה שיטה לכל פועל HTTP.

דלק תומך בכל פעלים HTTP למעט PATCH. הסיבה היא ש דלק HttpClient הוא עטיפה מעל java.net.HttpUrlConnection שאינו תומך ב- PATCH.

כדי לנקוט בצד הבעיה, HttpClient ממיר בקשות PATCH לבקשת POST ומוסיף X-HTTP- שיטת עקיפה: תיקון כותרת, לכן נצטרך לוודא שממשקי ה- API שלנו מוגדרים לקבלת כותרת זו כברירת מחדל.

על מנת להסביר את התכונות של Fuel, אנו נשתמש ב- httpbin.org, שירות בקשות ותגובות HTTP פשוט, ו- JsonPlaceholder - ממשק API מקוון מזויף לבדיקה ואב טיפוס.

3.1. קבל בקשה

נתחיל ליצור HTTP פשוט לקבל בקשה במצב אסינכרון:

"//httpbin.org/get".httpGet().response {בקשה, תגובה, תוצאה -> // טיפול בתגובה}

באמצעות httpGet () מעל ל חוּט נותן לנו לְשַׁלֵשׁ.

ה תוֹצָאָה הוא מבנה נתונים בסגנון פונקציונלי המכיל את תוצאת הפעולה (הצלחה או כישלון). נבקר שוב תוֹצָאָה מבנה נתונים בשלב מאוחר יותר.

אנו יכולים גם להגיש את הבקשה במצב חסימה:

val (בקשה, תגובה, תוצאה) = "//httpbin.org/get" .httpGet (). תגובה ()

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

כמו כן, קיימת אפשרות להשתמש בפארמים מקודדים של כתובות אתרים:

val (בקשה, תגובה, תוצאה) = "//jsonplaceholder.typicode.com/posts" .httpGet (listOf ("userId" ל- "1")). תגובה () // פתרון ל- //jsonplaceholder.typicode.com/ פוסטים? userId = 1 

ה httpGet () השיטה (ושאר הדומות) יכולות לקבל א רשימה לקידוד פרמטרים של כתובות אתרים.

3.2. בקשת POST

אנו יכולים להגיש בקשות POST באותו אופן כמו ל- GET באמצעות httpPost () או באמצעות הודעה() שיטת ה- דלק מעמד:

"//httpbin.org/post".httpPost (). תגובה {בקשה, תגובה, תוצאה -> // טיפול בתגובה}
val (בקשה, תגובה, תוצאה) = Fuel.post ("// httpbin.org/post"). תגובה () 

אם יש לנו גוף, נוכל להעביר אותו גוּף() שיטה בפורמט מחרוזת JSON:

val bodyJson = "" "{" title ":" foo "," body ":" bar "," id ":" 1 "}" "" val (בקשה, תגובה, תוצאה) = Fuel.post ("// jsonplaceholder.typicode.com/posts ") .body (bodyJson). תגובה ()

3.3. פעלים אחרים

כמו לגבי GET ו- POST, יש שיטה לכל אחד מהפועלים הנותרים:

Fuel.put ("// httpbin.org/put") Fuel.delete ("// httpbin.org/delete") Fuel.head ("// httpbin.org/get") Fuel.patch ("// httpbin .org / patch ")

זכור את זה Fuel.patch () יבצע בקשת POST עםX-HTTP- שיטת עקיפה: תיקון כּוֹתֶרֶת.

4. תצורה

הספרייה מספקת חפץ יחיד - FuelManager.instance - לניהול תצורה גלובלית.

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

4.1. BasePath

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

FuelManager.instance.basePath = "//httpbin.org" val (בקשה, תגובה, תוצאה) = "/ get".httpGet (). תגובה () // יבצע GET //httpbin.org/get

4.2. כותרות

יתר על כן, אנו יכולים לנהל כותרות HTTP נפוצות באמצעות baseHeaders מַפָּה:

FuelManager.instance.baseHeaders = mapOf ("מערכת הפעלה" ל"דביאן ")

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

val (בקשה, תגובה, תוצאה) = "/ get" .httpGet () .header (mapOf ("OS" ל- "Debian")). תגובה ()

4.3. פאראמים

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

FuelManager.instance.baseParams = listOf ("foo" ל "bar")

4.4. אפשרויות אחרות

ישנן אפשרויות רבות נוספות שנוכל לנהל באמצעותן FuelManager:

  • חנות מפתחות שהוא ריק כברירת מחדל
  • שקע מפעל שיסופק על ידי המשתמש או יופק מ- חנות מפתחות אם זה לא ריק
  • hostnameVerifier שמוגדר כברירת מחדל לשימוש בזה שמספק חיבור HttpsURLC מעמד
  • בקשה מיירטים ו תגובה מיירטים
  • פסק זמן ו זמן קצוב לקרוא לבקשה

4.5. מיירטים בקשה / תגובה

לגבי מיירטים, אנחנו יכולים להוסיף מיירטים לבקשות / תגובה שסופקו cUrlLoggingRequestInterceptors (), או שאנחנו יכולים להגדיר את שלנו:

FuelManager.instance.addRequestInterceptor (cUrlLoggingRequestInterceptor ()) 
FuelManager.instance.addRequestInterceptor (tokenInterceptor ()) fun tokenInterceptor () = {הבא: (Request) -> Request -> {req: Request -> req.header (mapOf ("Authorization" to "Bearer AbCdEf123456")) הבא ( req)}}

5. טיפול בתגובה

בעבר הצגנו מבנה נתונים פונקציונלי - תוֹצָאָה - המייצג את תוצאת הפעולה (הצלחה או כישלון).

עובד עם תוֹצָאָה קל, זהו מחלקת נתונים שיכולה להכיל את התגובה ב- ByteArray, מחרוזת, JSON, או גנרי ט לְהִתְנַגֵד:

תגובה מהנה (מטפל: (בקשה, תגובה, תוצאה) -> יחידה) תגובה מהנה מחרוזת (מטפל: (בקשה, תגובה, תוצאה) -> יחידה) תגובה מהנה ג'סון (מטפל: (בקשה, תגובה, תוצאה) -> יחידה) תגובה מהנה (deserializer: ResponseDeserizable, מטפל: (בקשה, תגובה, תוצאה) -> יחידה) 

בואו נקבל תגובה כ חוּט כדי להמחיש זאת:

val (בקשה, תגובה, תוצאה) = Fuel.post ("// httpbin.org/post") .responseString () val (מטען, שגיאה) = תוצאה // מטען הוא מחרוזת

שים לב שהתגובה בפורמט JSON דורשת תלות ב- Android.

 com.github.kittinunf.fuel fuel-android $ {fuel.version} 

6. סדרת JSON / Deserialization

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

deserialize כיף ציבורי (בתים: ByteArray): T? deserialize כיף ציבורי (inputStream: InputStream): T? כיף ציבורי מבטל את הערעור (קורא: קורא): T? deserialize כיף ציבורי (תוכן: מחרוזת): T?

על ידי הכללת מודול ה- Gson, אנו יכולים לבטל את ערכי סדר ולסדר אובייקטים:

מחלקת נתונים הודעה (var userId: Int, var id: Int, var title: String, var body: String) {class Deserializer: ResponseDeserializable {לעקוף כיף deserialize (תוכן: מחרוזת): מערך = Gson (). fromJson (תוכן, מערך :: class.java)}}

אנו יכולים לבטל את ערעור האובייקטים באמצעות deserializer המותאם אישית:

"//jsonplaceholder.typicode.com/posts" .httpGet (). responseObject (Post.Deserializer ()) {_, _, result -> val postsArray = result.component1 ()}

או באמצעות responseObject המשתמשת בניתוק deserializer פנימי של Gson:

"//jsonplaceholder.typicode.com/posts/1" .httpGet (). responseObject {_, _, result -> val post = result.component1 ()}

מצד שני, אנחנו יכולים לעשות סדרתי באמצעות Gson (). ToJson ():

val post = Post (1, 1, "Lorem", "Lorem Ipse dolor sit amet") val (בקשה, תגובה, תוצאה) = Fuel.post ("// jsonplaceholder.typicode.com/posts"). כותרת (" סוג תוכן "ל-" application / json "). גוף (Gson (). ToJson (פוסט) .toString ())

חשוב להגדיר את סוג תוכןאחרת, השרת עשוי לקבל את האובייקט בתוך אובייקט JSON אחר.

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

7. הורד והעלה קובץ

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

7.1. הורד

עם ה הורד() אנו יכולים להוריד קובץ בקלות ולשמור אותו בקובץ שהוחזר על ידי יַעַד() למבדה:

Fuel.download ("// httpbin.org/bytes/32768"). יעד {תגובה, url -> File.createTempFile ("temp", ".tmp")}

אנו יכולים גם להוריד קובץ עם מטפל בהתקדמות:

Fuel.download ("// httpbin.org/bytes/327680"). התקדמות {readBytes, totalBytes -> val progress = readBytes.toFloat () / totalBytes.toFloat () // ...}

7.2. העלה

באותה הדרך, נוכל להעלות קובץ באמצעות העלה () שיטה, המציין את הקובץ להעלאה עם מָקוֹר() שיטה:

Fuel.upload ("/ upload"). מקור {בקשה, url -> File.createTempFile ("temp", ".tmp")}

ציין זאת העלה () משתמש בפועל POST כברירת מחדל. אם אנו רוצים להשתמש בפועל HTTP אחר נוכל לציין אותו:

Fuel.upload ("/ upload", Method.PUT). Source {request, url -> File.createTempFile ("temp", ".tmp")}

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

Fuel.upload ("/ post"). מקורות {בקשה, url -> listOf (File.createTempFile ("temp1", ".tmp"), File.createTempFile ("temp2", ".tmp"))}

לבסוף, אנו יכולים להעלות כתם נתונים מ- InputStream:

Fuel.upload ("/ post"). Blob {בקשה, url -> Blob ("filename.png", someObject.length, {someObject.getInputStream ()})}

8. תמיכה ב- RxJava ו- Coroutines

דלק מספק תמיכה ב- RxJava ו- Coroutines, שתי דרכים לכתוב אסינכרונוס, קוד שאינו חוסם.

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

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

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

8.1. RxJava

כדי לתמוך ב- RxJava 2.x, דלק מספק שש תוספות:

fun Request.rx_response (): יחיד<>> כיף Request.rx_responseString (charset: Charset): יחיד<>> כיף Request.rx_responseObject (ניתן לביטול הערכה: ניתן לבטל אפשרות לביטול): יחיד<>> כיף Request.rx_data (): יחיד fun Request.rx_string (charset: Charset): יחיד fun Request.rx_object (ניתן לביטול הניתנים לעריכה: ניתן לבטל את הניתוב לביטול): יחיד

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

אנו יכולים להשתמש בשיטות "Rx" בקלות על ידי הפעלת השיטה הרלוונטית יותר על פני א בַּקָשָׁה:

 "//jsonplaceholder.typicode.com/posts?id=1" .httpGet (). rx_object (Post.Deserializer ()). הירשם {res, זורק -> val post = res.component1 ()}

8.2. קורוטינים

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

כדי להשתמש ב- Coroutines, ממשקי API דומים זמינים, למשל responseString () הפכתי awaitStringResponse ():

runBlocking {Fuel.get ("// httpbin.org/get"). awaitStringResponse ()}

הוא גם מספק שיטות שימושיות לטיפול בחפצים שאינם חוּט אוֹ ByteArray (awaitByteArrayResponse ()) באמצעות awaitObject (), awaitObjectResult () או awaitObjectResponse ():

runBlocking {Fuel.get ("// jsonplaceholder.typicode.com/posts?id=1") .awaitObjectResult (Post.Deserializer ())}

זכור כי Coroutines של Kotlin הם ניסיוניים, מה שאומר שזה עשוי להשתנות במהדורות הקרובות.

9. ניתוב API

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

בעזרת דפוס הנתב אנו יכולים לרכז את ניהול ה- API באמצעות ה- FuelRouting ממשק, המספק שילוב של שיטות להגדרת פועל HTTP המתאים, נתיב, פאראמס וכותרות על פי נקודת הקצה שנקראת.

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

מחלקה אטומה PostRoutingAPI: FuelRouting {class posts (val userId: String, override val body: String?): PostRoutingAPI () comments class (val postId: String, override val body: String?): PostRoutingAPI () override val basePath = "/ /jsonplaceholder.typicode.com "עקיפת שיטת val: שיטה get () {return when (this) {is PostRoutingAPI.posts -> Method.GET is PostRoutingAPI.comments -> Method.GET}} עקיפת נתיב val: String get () {לחזור כאשר (זה) {הוא PostRoutingAPI.posts -> "/ posts" הוא PostRoutingAPI.comments -> "/ comments"}} לעקוף val params: רשימה? get () {return when (this) {is PostRoutingAPI.posts -> listOf ("userId" to this.userId) is PostRoutingAPI.comments -> listOf ("postId" to this.postId)}} עקף כותרות שווי: מפה? קבל () {החזר null}}

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

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

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

Fuel.request (PostRoutingAPI.posts ("1", null)) .responseObject (Post.Deserializer ()) {בקשה, תגובה, תוצאה -> // טיפול בתגובה}
Fuel.request (PostRoutingAPI.comments ("1", null)) .responseString {בקשה, תגובה, תוצאה -> // טיפול בתגובה}

10. מסקנה

במאמר זה הראינו את ספריית ה- Fuel HTTP עבור Kotlin ואת התכונות היעילות יותר שלה לכל מקרה שימוש.

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

כרגיל, כל קטעי הקוד המוזכרים במדריך נמצאים במאגר GitHub שלנו.


$config[zx-auto] not found$config[zx-overlay] not found