OkHttp 请求构建和响应处理的完整流程
一、请求构建流程代码示例
1. GET 请求构建
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| val client = OkHttpClient()
val request = Request.Builder() .url("https://api.example.com/users") .header("Authorization", "Bearer token123") .addHeader("Accept", "application/json") .get() .tag(String::class.java, "用户列表请求") .build()
val response = client.newCall(request).execute()
|
2. POST 请求构建 (JSON 数据)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| val json = """ { "username": "test_user", "password": "test_password" } """.trimIndent()
val mediaType = "application/json; charset=utf-8".toMediaType() val requestBody = json.toRequestBody(mediaType)
val request = Request.Builder() .url("https://api.example.com/login") .header("Content-Type", "application/json") .post(requestBody) .build()
val response = client.newCall(request).execute()
|
3. POST 表单提交
1 2 3 4 5 6 7 8 9 10 11
| val formBody = FormBody.Builder() .add("username", "test_user") .add("password", "test_password") .build()
val request = Request.Builder() .url("https://api.example.com/login") .post(formBody) .build()
|
4. 文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| val file = File("/path/to/file.jpg") val mediaType = "image/jpeg".toMediaType() val requestFile = file.asRequestBody(mediaType)
val multipartBody = MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("title", "Profile Picture") .addFormDataPart("image", "file.jpg", requestFile) .build()
val request = Request.Builder() .url("https://api.example.com/upload") .post(multipartBody) .build()
|
二、响应处理流程代码示例
1. 基本响应处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| val response = client.newCall(request).execute()
try { if (response.isSuccessful) { val statusCode = response.code val headers = response.headers
val responseBody = response.body val responseString = responseBody?.string()
println("响应成功: $statusCode") println("响应内容: $responseString") } else { println("请求失败: ${response.code}") println("错误信息: ${response.message}") } } finally { response.close() }
|
2. JSON 响应处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| val gson = Gson()
try { if (response.isSuccessful) { val responseBody = response.body
val jsonString = responseBody?.string()
data class User(val id: Int, val name: String, val email: String) val user = gson.fromJson(jsonString, User::class.java)
println("用户ID: ${user.id}") println("用户名: ${user.name}") println("邮箱: ${user.email}") } } finally { response.close() }
|
3. 流式处理大文件下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| val request = Request.Builder() .url("https://example.com/large-file.zip") .build()
val response = client.newCall(request).execute()
try { if (!response.isSuccessful) { throw IOException("下载失败: ${response.code}") }
val responseBody = response.body ?: throw IOException("响应体为空")
val downloadFile = File("/path/to/save/file.zip") val outputStream = FileOutputStream(downloadFile)
val sink = outputStream.sink().buffer()
val source = responseBody.source()
val bufferSize = 8 * 1024 val buffer = Buffer() var bytesRead: Long
val contentLength = responseBody.contentLength() var totalBytesRead = 0L
while (source.read(buffer, bufferSize.toLong()).also { bytesRead = it } != -1L) { sink.write(buffer, bytesRead) totalBytesRead += bytesRead
if (contentLength > 0) { val progress = (totalBytesRead * 100 / contentLength).toInt() println("下载进度: $progress%") } }
sink.flush() sink.close()
println("文件下载完成: ${downloadFile.absolutePath}") } finally { response.close() }
|
4. 异步请求与响应处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { println("请求失败: ${e.message}") }
override fun onResponse(call: Call, response: Response) { try { if (response.isSuccessful) { val responseData = response.body?.string() println("异步请求成功: $responseData")
} else { println("请求返回错误: ${response.code}") } } finally { response.close() } } })
|
三、请求和响应的完整生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| val client = OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build()
val request = Request.Builder() .url("https://api.example.com/data") .header("User-Agent", "OkHttp Example") .build()
val call = client.newCall(request)
val response = call.execute()
try { val statusCode = response.code
val contentType = response.header("Content-Type")
if (response.isSuccessful) { val responseBody = response.body
when { contentType?.contains("application/json") == true -> { val jsonString = responseBody?.string() println("JSON响应: $jsonString") } contentType?.contains("text/") == true -> { val textResponse = responseBody?.string() println("文本响应: $textResponse") } else -> { val bytes = responseBody?.bytes() println("二进制响应长度: ${bytes?.size} 字节") } } } else { println("错误: ${response.code} ${response.message}") } } catch (e: Exception) { println("处理响应时发生异常: ${e.message}") } finally { response.close() }
|
以上代码示例展示了 OkHttp 请求构建和响应处理的完整流程,包括:
- 不同类型的请求构建(GET、POST、文件上传等)
- 各种响应处理方式(字符串、JSON、文件下载等)
- 同步和异步请求的处理差异
- 完整的请求-响应生命周期管理
这些示例可以作为实际开发中的参考模板。