рдореБрдЭреЗ Android рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ Retrofit2 рдкрд╕рдВрдж рд╣реИ, рд▓реЗрдХрд┐рди Ktor HTTP рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдпрд╣ рдХреЛрдИ рднреА рдмрджрддрд░ рдФрд░ рдмреЗрд╣рддрд░ рдирд╣реАрдВ рд╣реИ, рдмрд╕ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрджрд┐ рдЖрдк рд╕рдм рдХреБрдЫ рдереЛрдбрд╝рд╛ рд▓рдкреЗрдЯрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рдЙрди рдмреБрдирд┐рдпрд╛рджреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдВрдЧрд╛ рдЬрд┐рдирдХреЗ рд╕рд╛рде Ktor рдХреЛ HTTP рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ - рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрд░реЛрдз рдмрдирд╛рдирд╛, рдкрд╛рда рдХреЗ рд░реВрдк рдореЗрдВ рдХрдЪреНрдЪреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдПрдВ рдФрд░ рдЙрддреНрддрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛, рдХрдиреНрд╡рд░реНрдЯрд░реНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдбрд╕рдирд░рд▓рд╛рдЗрдЬрд╝ рдХрд░рдирд╛, рдФрд░ рд▓реЙрдЧрд┐рдВрдЧред

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, Ktor рдПрдХ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реИ рдЬреЛ HTTP рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рдЗрд╕реЗ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд╛рд╕ рдХреА рдУрд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдВрдЧрд╛ред рдпрд╣ рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдк рдмрд╣реБрдд рд╣реА рдЬрдЯрд┐рд▓ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓реЛрдВ рдХреЗ рдиреАрдЪреЗ рджреЗрдЦреЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдореВрд▓ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╕рдЯреАрдХ рд╣реИрдВред рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рдХреЛрдб рдХреЛ
GitHub рдкрд░ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛
рд╣реИ ред
Ktor рдиреЗ рдХреЛрдЯрд▓рд┐рди 1.3 рдХреЗ рдХреЙрд░рдЖрдЙрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ, рдЙрдкрд▓рдмреНрдз рдХрд▓рд╛рдХреГрддрд┐рдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА
рдпрд╣рд╛рдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА
рд╣реИ , рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг
1.0.1
ред
рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП, рдореИрдВ
HttpBin рдХрд╛ рдЙрдкрдпреЛрдЧ
рдХрд░реВрдВрдЧрд╛ ред
рд╕рд░рд▓ рдЙрдкрдпреЛрдЧ
рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдВрдбреНрд░реЙрдЗрдб рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рдирд┐рд░реНрднрд░рддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
implementation "io.ktor:ktor-client-core:1.0.1" implementation "io.ktor:ktor-client-android:1.0.1"
рдореЗрдирд┐рдлреЗрд╕реНрдЯ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдордд рднреВрд▓рдирд╛ рдХрд┐ рдЖрдк рдЗрдВрдЯрд░рдиреЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
<uses-permission android:name="android.permission.INTERNET"/>
рдЪрд▓реЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд░реНрд╡рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ, рдХреНрдпрд╛ рдЖрд╕рд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ?
private const val BASE_URL = "https://httpbin.org" private const val GET_UUID = "$BASE_URL/uuid" fun simpleCase() { val client = HttpClient() GlobalScope.launch(Dispatchers.IO) { val data = client.get<String>(GET_UUID) Log.i("$BASE_TAG Simple case ", data) } }
рдЖрдк рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдЧреНрд░рд╛рд╣рдХ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд╕
HttpClient()
рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдПрдВред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, Ktor рд╡рд╛рдВрдЫрд┐рдд рдЗрдВрдЬрди рдХрд╛ рдЪрдпрди рдХрд░реЗрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ (рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЗрдВрдЬрди рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ - Android, рд▓реЗрдХрд┐рди рдЕрдиреНрдп рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, OkHttp)ред
рдХреЛрд░рдЯрд╛рдЗрди рдХреНрдпреЛрдВ? рдХреНрдпреЛрдВрдХрд┐
get()
рдПрдХ
suspend
рдлрдВрдХреНрд╢рди рд╣реИред
рдЖрдЧреЗ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ? рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╕рд░реНрд╡рд░ рд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдбреЗрдЯрд╛ рд╣реИ, рдпрд╣ рдЗрд╕реЗ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдФрд░ рдЙрди рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рд░рд▓ рдФрд░ рддреЗрдЬ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИред
рд╣рдореЗрдВ рдПрдХ рдХрдЪреНрдЪрд╛ рдЬрд╡рд╛рдм рдорд┐рд▓рддрд╛ рд╣реИ
рдХрднреА-рдХрднреА рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдмрдЬрд╛рдп рдмрд╛рдЗрдЯреНрд╕ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕реА рд╕рдордп, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░реЗрдВред
fun performAllCases() { GlobalScope.launch(Dispatchers.IO) { simpleCase() bytesCase() } } suspend fun simpleCase() { val client = HttpClient() val data = client.get<String>(GET_UUID) Log.i("$BASE_TAG Simple case", data) } suspend fun bytesCase() { val client = HttpClient() val data = client.call(GET_UUID).response.readBytes() Log.i("$BASE_TAG Bytes case", data.joinToString(" ", "[", "]") { it.toString(16).toUpperCase() }) }
рдЙрди рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдЬрд╣рд╛рдВ
HttpClient
рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ
call()
HttpClient
, рдЬреИрд╕реЗ
call()
рдФрд░
get()
,
await()
рдХреЛ рд╣реБрдб рдХреЗ рдиреАрдЪреЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рддреЛ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ
simpleCase()
рдФрд░
bytesCase()
рд▓рд┐рдП рдХреЙрд▓ рд╣рдореЗрд╢рд╛ рдЕрдиреБрдХреНрд░рдорд┐рдХ рд╣реЛрдВрдЧреЗред рдЖрдкрдХреЛ рдЗрд╕реЗ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдЪрд╛рд╣рд┐рдП - рдмрд╕ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдХреЛрд░рдЯрд╛рдЗрди рдореЗрдВ рд▓рдкреЗрдЯреЗрдВред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдирдП рддрд░реАрдХреЗ рджрд┐рдЦрд╛рдИ рджрд┐рдП рд╣реИрдВред рдХреЙрд▓рд┐рдВрдЧ
call(GET_UUID)
рдПрдХ рдРрд╕реА рд╡рд╕реНрддреБ рд▓реМрдЯрд╛рдПрдЧрд╛ рдЬрд┐рд╕рд╕реЗ рд╣рдо рдЕрдиреБрд░реЛрдз, рдЙрд╕рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди, рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реА рдЙрдкрдпреЛрдЧреА рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрддреА рд╣реИ - рдПрдХ рд╣реА рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдЪреИрдирд▓ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛрдб рдФрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕рдВрд╕реНрдХрд░рдг рд╕реЗред
рдХреНрдпрд╛ рдЖрдкрдХреЛ рдЗрд╕реЗ рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рдмрдВрдж рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?
рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ HTTP рдЗрдВрдЬрди рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░
close()
рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрджрд┐ рдЖрдкрдХреЛ рдПрдХ рдХреЙрд▓ рдХрд░рдиреЗ рдФрд░ рддреБрд░рдВрдд рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ
use{}
рд╡рд┐рдзрд┐, рдЪреВрдВрдХрд┐
HttpClient
Closable
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
suspend fun closableSimpleCase() { HttpClient().use { val data: String = it.get(GET_UUID) Log.i("$BASE_TAG Closable case", data) } }
рдЬреАрдИрдЯреА рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЙрджрд╛рд╣рд░рдг
рдореЗрд░реЗ рдХрд╛рдо рдореЗрдВ, рджреВрд╕рд░рд╛ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рддрд░реАрдХрд╛
POST
ред рдорд╛рдкрджрдВрдбреЛрдВ, рд╢реАрд░реНрд╖рдХреЛрдВ рдФрд░ рдЕрдиреБрд░реЛрдз рдирд┐рдХрд╛рдп рдХреА рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
suspend fun postHeadersCase(client: HttpClient) { val data: String = client.post(POST_TEST) { fillHeadersCaseParameters() } Log.i("$BASE_TAG Post case", data) } private fun HttpRequestBuilder.fillHeadersCaseParameters() { parameter("name", "Andrei")
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ,
post()
рдХреЗ рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдореАрдЯрд░
post()
рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдЖрдкрдХреЗ рдкрд╛рд╕
HttpRequestBuilder
рддрдХ рдкрд╣реБрдВрдЪ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдЖрдк рдХреЛрдИ рднреА рдЕрдиреБрд░реЛрдз рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред
post()
рд╡рд┐рдзрд┐ рдмрд╕ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреА рд╣реИ, рдЗрд╕реЗ URL рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддреА рд╣реИ, рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд┐рдзрд┐ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╕реЗрдЯ рдХрд░рддреА рд╣реИ, рдФрд░ рдПрдХ рдЕрдиреБрд░реЛрдз рдХрд░рддреА рд╣реИред
suspend fun rawPostHeadersCase(client: HttpClient) { val data: String = client.call { url.takeFrom(POST_TEST) method = HttpMethod.Post fillHeadersCaseParameters() } .response .readText() Log.i("$BASE_TAG Raw post case", data) }
рдпрджрд┐ рдЖрдк рдЕрдВрддрд┐рдо рджреЛ рд╡рд┐рдзрд┐рдпреЛрдВ рд╕реЗ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкрд░рд┐рдгрд╛рдо рд╕рдорд╛рди рд╣реЛрдЧрд╛ред рдЕрдВрддрд░ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд░реИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рд╕реНрдерд┐рддрд┐
put()
,
delete()
,
patch()
,
head()
рдФрд░
options()
, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЙрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдЧрд░ рдЖрдк рдмрд╛рд░реАрдХреА рд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдореЗрдВ рдЕрдВрддрд░ рд╣реИред рдЬрдм рдЖрдк рдХреЙрд▓
call()
рддреЛ рдЖрдкрдХреЛ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдЙрддреНрддрд░ рдорд┐рд▓рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рд╕реНрд╡рдпрдВ рдбреЗрдЯрд╛ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛? рдЖрдЦрд┐рд░рдХрд╛рд░, рд╣рдо рд╕рднреА рдХреЛ рд░реЗрдЯреНрд░реЛрдлрд┐рдЯ 2 рдореЗрдВ рдПрдХ рдХрдирд╡рд░реНрдЯрд░ (рдЬреИрд╕реЗ
Gson
) рд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдФрд░ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд░реНрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдмрд╛рдж рдореЗрдВ рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди
request
рд╡рд┐рдзрд┐ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ HTTP рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд┐рдП рдмрд┐рдирд╛ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧреАред
suspend fun typedRawPostHeadersCase(client: HttpClient) { val data = client.request<String>() { url.takeFrom(POST_TEST) method = HttpMethod.Post fillHeadersCaseParameters() } Log.i("$BASE_TAG Typed raw post", data) }
рдлреЙрд░реНрдо рдбреЗрдЯрд╛ рдЬрдорд╛ рдХрд░реЗрдВ
рдЖрдорддреМрд░ рдкрд░ рдЖрдкрдХреЛ рдХреНрд╡реЗрд░реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рдмреЙрдбреА рдореЗрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдКрдкрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдВрдЪ рдХрд░ рдЪреБрдХреЗ рд╣реИрдВ рдХрд┐
HttpRequestBuilder
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдпрд╣ рдХреИрд╕реЗ рдХрд░реЗрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдЖрд╕рд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
submitForm
рдлрд╝рдВрдХреНрд╢рди url рдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рдПрдХ рдмреВрд▓рд┐рдпрди рдзреНрд╡рдЬ рдЬреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реИ - рдЕрдиреБрд░реЛрдз рдкрдВрдХреНрддрд┐ рдореЗрдВ рдпрд╛ рдкреНрд░рдкрддреНрд░ рдореЗрдВ рдЬреЛрдбрд╝реЗ рдХреЗ рд░реВрдк рдореЗрдВред
suspend fun submitFormCase(client: HttpClient) { val params = Parameters.build { append("Star", "Sun") append("Planet", "Mercury") } val getData: String = client.submitForm(GET_TEST, params, encodeInQuery = true)
рд▓реЗрдХрд┐рди рдорд▓реНрдЯреАрдкрд╛рд░реНрдЯ / рдлреЙрд░реНрдо-рдбреЗрдЯрд╛ рдХрд╛ рдХреНрдпрд╛?
рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЬреЛрдбрд╝реЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдкреИрд░рд╛рдореАрдЯрд░ POST рдЕрдиреБрд░реЛрдз рд╕рдВрдЦреНрдпрд╛, рдмрд╛рдЗрдЯ рд╕рд░рдгрд┐рдпреЛрдВ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдЗрдирдкреБрдЯ рдзрд╛рд░рд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдЧрдарди рдореЗрдВ рдЕрдВрддрд░ред рд╣рдо рдЬреИрд╕реЗ рджрд┐рдЦрддреЗ рд╣реИрдВ:
suspend fun submitFormBinaryCase(client: HttpClient) { val inputStream = ByteArrayInputStream(byteArrayOf(77, 78, 79)) val formData = formData { append("String value", "My name is")
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рджреЗрдЦрд╛ рд╣реЛрдЧрд╛ - рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рд╣реЗрдбрд░ рдХрд╛ рдПрдХ рд╕реЗрдЯ рднреА рд╕рдВрд▓рдЧреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдХрдХреНрд╖рд╛ рдХреЗ рдЙрддреНрддрд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ
рдЖрдкрдХреЛ рдЕрдиреБрд░реЛрдз рд╕реЗ рдХреБрдЫ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рди рдХрд┐ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдмрд▓реНрдХрд┐ рддреБрд░рдВрдд рдПрдХ рд╡рд░реНрдЧ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рд▓рд╛рд╣ рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо json рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдПрдХ рдЖрд░рдХреНрд╖рдг рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ jvm рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд┐рд░реНрднрд░рддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдФрд░ kotlinx-serialization рдХреЗ рдмрд┐рдирд╛ рдпрд╣ рд╕рдм рджреВрд░ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдореИрдВ рдПрдХ рдХрдирд╡рд░реНрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ Gson рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ (рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдЕрдиреНрдп рд╕рдорд░реНрдерд┐рдд рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд▓рд┐рдВрдХ рд╣реИрдВ, рдкреНрд░рд▓реЗрдЦрди рдХреЗ рд▓рд┐рдВрдХ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╣реЛрдВрдЧреЗ)ред
рдмрд┐рд▓реНрдб.рдЧреНрд░реЗрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реНрддрд░:
buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" } } allprojects { repositories { maven { url "https://kotlin.bintray.com/kotlinx" } } }
build.gradle рдЖрд╡реЗрджрди рд╕реНрддрд░:
apply plugin: 'kotlinx-serialization' dependencies { implementation "io.ktor:ktor-client-json-jvm:1.0.1" implementation "io.ktor:ktor-client-gson:1.0.1" }
рдЕрдм рдЕрдиреБрд░реЛрдз рдкрд░ рдЕрдорд▓ рдХрд░реЗрдВред рдирдП рд╕реЗ, рдХреНрд▓рд╛рдЗрдВрдЯ рдмрдирд╛рддреЗ рд╕рдордп рдХреЗрд╡рд▓ Json рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдПрдХ рдХрдиреЗрдХреНрд╢рди рд╣реЛрдЧрд╛ред рдореИрдВ рдЦреБрд▓реЗ рдореМрд╕рдо рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ред рдкреВрд░реНрдгрддрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдбреЗрдЯрд╛ рдореЙрдбрд▓ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред
data class Weather( val consolidated_weather: List<ConsolidatedWeather>, val time: String, val sun_rise: String, val sun_set: String, val timezone_name: String, val parent: Parent, val sources: List<Source>, val title: String, val location_type: String, val woeid: Int, val latt_long: String, val timezone: String ) data class Source( val title: String, val slug: String, val url: String, val crawl_rate: Int ) data class ConsolidatedWeather( val id: Long, val weather_state_name: String, val weather_state_abbr: String, val wind_direction_compass: String, val created: String, val applicable_date: String, val min_temp: Double, val max_temp: Double, val the_temp: Double, val wind_speed: Double, val wind_direction: Double, val air_pressure: Double, val humidity: Int, val visibility: Double, val predictability: Int ) data class Parent( val title: String, val location_type: String, val woeid: Int, val latt_long: String ) private const val SF_WEATHER_URL = "https://www.metaweather.com/api/location/2487956/" suspend fun getAndPrintWeather() { val client = HttpClient(Android) { install(JsonFeature) { serializer = GsonSerializer() } } val weather: Weather = client.get(SF_WEATHER_URL) Log.i("$BASE_TAG Serialization", weather.toString()) }
рдФрд░ рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рд░реНрд╡рд░ рдПрдХ рддреНрд░реБрдЯрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрдб рд╣реИред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЖрдкрдХреЛ рдПрдХ рдХреНрд░рдорд╛рдВрдХрди рддреНрд░реБрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рдЖрдк рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛрдб <300 рд╣реЛрдиреЗ рдкрд░
BadResponseStatus
рддреНрд░реБрдЯрд┐ рдХреЛ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рдПред рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рджреМрд░рд╛рди рдпрд╣
expectSuccess
рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред
val client = HttpClient(Android) { install(JsonFeature) { serializer = GsonSerializer() } expectSuccess = true }
рдбрд┐рдмрдЧрд┐рдВрдЧ рдХрд░рддреЗ рд╕рдордп, рд▓реЙрдЧрд┐рдВрдЧ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреА рд╣реИред рдмрд╕ рдПрдХ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред
implementation "io.ktor:ktor-client-logging-jvm:1.0.1"
val client = HttpClient(Android) { install(Logging) { logger = Logger.DEFAULT level = LogLevel.ALL } }
рд╣рдо DEFAULT рд▓рдХрдбрд╝рд╣рд╛рд░реЗ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕рдм рдХреБрдЫ LogCat рдкрд░ рдЪрд▓рд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ рддреЛ рдЖрдк рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рд╡рд╣рд╛рдБ рдХреЛрдИ рдорд╣рд╛рди рдЕрд╡рд╕рд░ рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ, рдЗрдирдкреБрдЯ рдкрд░ рдХреЗрд╡рд▓ рдПрдХ рд╕рдВрджреЗрд╢ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛрдИ рд▓реЙрдЧ рд╕реНрддрд░ рдирд╣реАрдВ рд╣реИ)ред рд╣рдо рд▓реЙрдЧ рдХреЗ рд╕реНрддрд░ рдХреЛ рднреА рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕рдВрджрд░реНрдн:
рдХреНрдпрд╛ рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ:
- OkHttp рдЗрдВрдЬрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ
- рдЗрдВрдЬрди рд╕реЗрдЯрд┐рдВрдЧреНрд╕
- рдореЙрдХ рдЗрдВрдЬрди рдФрд░ рдкрд░реАрдХреНрд╖рдг
- рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдореЙрдбреНрдпреВрд▓
- рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдЬреИрд╕реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдмреАрдЪ рдХреБрдХреАрдЬрд╝ рдХреЛ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд░рдирд╛, рдЖрджрд┐ред
- рд╕рдм рдХреБрдЫ рдЬреЛ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд▓рд┐рдП HTTP рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ (рдЕрдиреНрдп рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо, рд╕реЙрдХреЗрдЯреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд░рдирд╛, рд╕рд░реНрд╡рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рдЖрджрд┐ред