Kotlin okhttp simple package

Keywords: Java OkHttp Android JSON

The first time I wrote a blog, I felt a little excited.
Mainly make a record of the process of learning Kotlin. After all, a good memory is better than a bad pen. Although I haven't done it all the time, this may be the beginning.
Add dependency:

 implementation 'com.squareup.okhttp3:okhttp:3.1.2'
 implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.60'
 // There is a big hole here. Kotlin is not supported in fastjson versions other than 1.2.36 and 1.1.61. Hope the official website is updated as soon as possible
 implementation 'com.alibaba:fastjson:1.2.36'
 implementation 'com.alibaba:fastjson:1.1.61.android'

The first is the encapsulation of okhttp

import okhttp3.Interceptor
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit

class HttpManager private constructor() {

    var httpClient: OkHttpClient? = null
    val timeUnit: TimeUnit = TimeUnit.SECONDS
    val connectTimeOut: Long = 10
    val readTimeOut: Long = 10
    val writeTimeOut: Long = 10
    var interceptors: ArrayList<Interceptor> = ArrayList()
    var networkInterceptors: ArrayList<Interceptor> = ArrayList()

    companion object {
        fun instace() = Holder.INSTACE
    }

    private object Holder {
        val INSTACE = HttpManager()

        init {
            INSTACE.initHttpClient()
        }
    }

    fun initHttpClient(): OkHttpClient? {
        var builder = OkHttpClient.Builder()
                .connectTimeout(connectTimeOut, timeUnit)
                .readTimeout(readTimeOut, timeUnit)
                .writeTimeout(writeTimeOut, timeUnit)
        builder = initInterceptor(builder, interceptors)
        builder = initNetworkInterceptor(builder, networkInterceptors)
        httpClient = builder.build()
        return httpClient
    }

    fun addInterceptor(interceptors: ArrayList<Interceptor>) {
        this.interceptors = interceptors
    }

    fun addNetworkInterceptor(interceptors: ArrayList<Interceptor>) {
        this.networkInterceptors = interceptors
    }

    fun initInterceptor(builder: OkHttpClient.Builder?, interceptors: ArrayList<Interceptor>?): OkHttpClient.Builder? {
        interceptors?.forEach { i: Interceptor? ->
            if (i != null)
                builder?.addInterceptor(i)
        }
        return builder
    }

    fun initNetworkInterceptor(builder: OkHttpClient.Builder?, networkInterceptors: ArrayList<Interceptor>?): OkHttpClient.Builder? {
        networkInterceptors?.forEach { i: Interceptor? ->
            if (i != null)
                builder?.addNetworkInterceptor(i)
        }
        return builder
    }

}

Once okhttp is encapsulated, the request rquest can be encapsulated

import com.base.http.callback.AbstractCallback
import okhttp3.*
import java.io.IOException

class RequestManager {

    var okHttpClient: OkHttpClient? = null
    var builder: Request.Builder? = null

    init {
        builder = Request.Builder()
    }

    constructor() {
        okHttpClient = HttpManager.instace().httpClient
    }

    constructor(okHttpClient: OkHttpClient?) {
        if (okHttpClient == null)
            RequestManager()
        else
            this.okHttpClient = okHttpClient
    }

    fun doGet(url: String, headers: HashMap<String, String>? = null, params: HashMap<String, String>? = null): RequestManager {
        if (url.isBlank())
            return this
        if (headers != null)
            addHeaders(headers)
        builder!!.url(if (params != null) setGetParams(url, params) else url).get()
        return this
    }

    fun doPost(url: String, headers: HashMap<String, String>? = null, params: HashMap<String, String>? = null): RequestManager {
        if (url.isBlank())
            return this
        if (headers != null)
            addHeaders(headers)
        builder!!.url(url)
        builder!!.post(setPostParams(params))
        return this
    }

    fun addHeaders(headers: HashMap<String, String>) {
        headers.entries.forEach { entry ->
            headers.keys
            builder?.addHeader(entry.key, entry.value)
        }
    }

    fun setGetParams(url: String, params: HashMap<String, String>): String {
        var sb = StringBuilder(url)
        if (params.isNotEmpty()) sb.append("?") else sb
        params.forEach { entry ->
            params.keys
            sb.append(entry.key + "=" + entry.value + "&")
        }
        return if (sb.toString().endsWith("&")) sb.subSequence(0, sb.lastIndex).toString() else sb.toString()
    }

    fun setPostParams(params: HashMap<String, String>?): RequestBody? {
        var builder = FormBody.Builder()
        params?.forEach { entry ->
            params.keys
            builder.add(entry.key, entry.value)
        }
        return builder.build()
    }

    fun execute(abstractCallback: AbstractCallback) {
        okHttpClient!!.newCall(builder!!.build())?.enqueue(object : Callback {
            override fun onResponse(call: Call?, response: Response) {
                abstractCallback.succeed(call, response)
            }

            override fun onFailure(call: Call?, e: IOException?) {
                abstractCallback.failed(call, e)
            }
        })
    }
}

After the request is encapsulated, our callback can be processed uniformly. First of all, an abstract callback class is defined. Of course, there is no problem with the interface

import okhttp3.Call
import okhttp3.Response
import java.lang.Exception

abstract class AbstractCallback{
    abstract fun succeed(call: Call?, response: Response)

    abstract fun failed(call: Call?, e: Exception?)
}

After defining the abstract callback of the base class, we can inherit it to process our data. If string data is returned

import android.util.Log
import okhttp3.Call
import okhttp3.Response
import java.io.IOException

abstract class BasicCallback : AbstractCallback() {
    val TAG = BasicCallback::class.java.simpleName
    abstract fun succeed(call: Call?, result: String)

    override fun succeed(call: Call?, response: Response) {
        try {
            if (call!!.isCanceled()) {
                failed(call, IOException("Canceled!"))
                return
            }
            Log.e(TAG, "request:" + call.request().toString())
            Log.e(TAG, "response:" + response.toString())
            if (response.code() !in 200..299) { // Return Code is not in200-299request was aborted
                failed(call, IOException("request failed , reponse's code is : " + response.code()))
                return
            }
            val str = response.body()!!.string()
            Log.e(TAG, str)
            succeed(call, str)
        } catch (e: Exception) {
            Log.e(TAG, e.toString() + "")
            failed(call, e)
        } finally {
            if (response.body() != null)
                response.body()!!.close()
        }
    }

}

Because the server usually returns JSON data, I encapsulate a callback that directly returns the object. I use fastjson here.
fastjson parsing object method

class JsonParser {

    companion object {
        fun <T> parserToBean(jsonStr: String, clz: Class<T>) : T {
            return JSON.parseObject(jsonStr,clz)
        }
}

Return object callback class definition

import android.util.Log
import com.base.http.parser.JsonParser
import okhttp3.Call
import okhttp3.Response
import java.io.IOException

abstract class JsonCallback<T>(var clz: Class<T>) : AbstractCallback() {

    val TAG = JsonCallback::class.java.simpleName

    abstract fun succeed(call: Call?, data: T)

    override fun succeed(call: Call?, response: Response) {
        try {
            if (call!!.isCanceled()) {
                failed(call, IOException("Canceled!"))
                return
            }
            Log.e(TAG,"request:" + call.request().toString())
            Log.e(TAG,"response:" + response.toString())
            if (response.code() !in 200..299) {
                failed(call, IOException("request failed , reponse's code is : " + response.code()))
                return
            }
            val str = response.body()!!.string()
            Log.e(TAG,str)
            succeed(call, JsonParser.parserToBean(str, clz))
        } catch (e: Exception) {
            Log.e(TAG,e.toString() + "")
            failed(call, e)
        } finally {
            if (response.body() != null)
                response.body()!!.close()
        }
    }

}

After writing this simple package, I have finished writing, only post and get requests. File upload and download have not been added.
Finally, it's used

fun sendRequest() {
    val params = HashMap<String, String>()
    params["key"] = "value"
    requestManager.doPost(url,header,params).execute(object:JsonCallback<Bean>(Bean::class.java) {
                override fun succeed(call: Call?, data: Bean) {
                    // data is the return object

                }

                override fun failed(call: Call?, e: Exception?) {
                }

            })
        }

Finish writing and finish work. How about file upload and download? Come on

Posted by Buddha443556 on Mon, 06 Jan 2020 03:43:08 -0800