You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
4.2 KiB

package com.gyf.lib.util
import com.google.gson.Gson
import com.orhanobut.logger.Logger
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException
import java.lang.reflect.Type
import java.net.SocketTimeoutException
object HttpClient {
private val httpClient: OkHttpClient = OkHttpClient()
private val JSON_CONTENT_TYPE = "application/json; charset=UTF-8".toMediaType()
/**
* 构建url查询参数
*
* @param params
* @return
*/
private fun buildQueryParams(params: Map<String, String>?): String {
return if (params?.isNotEmpty() == true) {
val urlPath = StringBuilder("?")
for (i in params) {
urlPath.append(i.key).append("=").append(i.value)
}
urlPath.toString()
} else {
""
}
}
/**
* 构建表单参数
*
* @param params
* @return
*/
private fun buildFormBody(params: Map<String, String>?): FormBody {
val builder = FormBody.Builder()
if (params?.isNotEmpty() == true) {
for (item in params) {
builder.add(item.key, item.value)
}
}
return builder.build()
}
/**
* HTTP GET
*
* @param url
* @param callback
* @param params
*/
fun get(url: String, callback: Callback, params: Map<String, String>? = null) {
val request = Request.Builder()
.url(url.plus(buildQueryParams(params = params)))
.build()
val call = httpClient.newCall(request)
call.enqueue(callback)
}
/**
* HTTP POST
* 发送表单
*
* @param url
* @param callback
* @param params
*/
fun post(url: String, callback: Callback, params: Map<String, String>? = null) {
val request = Request.Builder()
.url(url)
.post(body = buildFormBody(params))
.build()
val call = httpClient.newCall(request)
call.enqueue(callback)
}
/**
* HTTP POST
* 发送JSON
*
* @param url
* @param callback
* @param jsonBody
*/
fun post(url: String, callback: Callback, jsonBody: String) {
Logger.json(jsonBody)
val request = Request.Builder()
.url(url)
.post(body = jsonBody.toRequestBody(contentType = JSON_CONTENT_TYPE))
.build()
val call = httpClient.newCall(request)
call.enqueue(callback)
}
}
/**
* 接口响应实体
*
* @param T
* @property code
* @property message
* @property body
*/
data class ApiResponse<T>(val code: Int, val message: String, val body: T? = null)
interface GsonBuilderInterface {
val gson: Gson
}
abstract class HttpCallback<T>(
private val action: String,
private val onSuccess: (res: ApiResponse<T>) -> Unit,
private val onFail: (error: String) -> Unit,
private val type: Type
) : Callback, GsonBuilderInterface {
override fun onFailure(call: Call, e: IOException) {
when (e) {
is SocketTimeoutException -> {
onFail("${action}失败,网络连接超时!")
}
else -> {
onFail("${action}失败,请联系管理员")
}
}
Logger.e(e, "${action}请求失败,发生IO异常")
}
override fun onResponse(call: Call, response: Response) {
if (response.code == 200) {
val body = response.body
if (body != null && body.contentType()?.subtype == "json") {
val jsonRes = body.string()
Logger.json(jsonRes)
val res: ApiResponse<T> = gson.fromJson(jsonRes, type)
Logger.i("json解析成功:$res")
onSuccess(res)
} else {
onFail("${action}失败,请联系管理员")
Logger.e("无法解析${action}请求响应数据:,响应码:${response.code},${response.body}")
}
} else {
onFail("${action}失败,请联系管理员")
Logger.e("${action}失败,请求响应码:${response.code}")
}
}
}