Retrofit总结(持续更新)

Get请求

@query

@Query会以key=value的方式拼接在url后面
Query非必填,如果请求参数非必填,可以传null
如:https://api.douban.com/v2/movie/top250?start=0&count=10

ApiServer.kt

@GET("top250")
fun getTopMovie(@Query("start") start: Int, @Query("count") count: Int): Call<ResponseEntity>

MainActivity.kt

@OnClick(R.id.tv_main)
fun getTopMovie() {
        val retrofit = Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl("https://api.douban.com/v2/movie/")
                .build()

        val apiService = retrofit.create(ApiServer::class.java)
        val call = apiService.getTopMovie(0, 10)
        call.enqueue(object : Callback<ResponseEntity> {
            override fun onFailure(call: Call<ResponseEntity>?, t: Throwable?) {

            }

            override fun onResponse(call: Call<ResponseEntity>?, response: Response<ResponseEntity>?) {
                Log.i("qfxl", "response = ${response?.body()}")
            }

        })
    }

@QueryMap

如果Query参数比较多,那么可以通过@QueryMap方式将所有的参数集成在一个Map。
如:https://api.douban.com/v2/movie/top250?start=0&count=10
ApiServer.kt

@GET("top250")
fun getTopMovie(@QueryMap params: Map<String, String>): Call<ResponseEntity>

MainActivity.kt

 @OnClick(R.id.tv_main)
    fun getTopMovie() {
        val retrofit = Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl("https://api.douban.com/v2/movie/")
                .build()

        val apiService = retrofit.create(ApiServer::class.java)
        val params = mapOf("start" to "0", "count" to "10")
        val call = apiService.getTopMovie(params)
        call.enqueue(object : Callback<ResponseEntity> {
            override fun onFailure(call: Call<ResponseEntity>?, t: Throwable?) {

            }
            override fun onResponse(call: Call<ResponseEntity>?, response: Response<ResponseEntity>?) {
                Log.i("qfxl", "response = ${response?.body()}")
            }

        })
    }

Query集合

假如需要添加相同Key值,但是value却有多个的情况,一种方式是添加多个@Query参数,还有一种简便的方式是将所有的value放置在列表中,然后在同一个@Query下完成添加
如:https://api.douban.com/v2/movie/top250?start=0&start=1
ApiServer.kt

 @GET("top250")
 fun getTopMovie(@Query("start") paramList: List<String>): Call<ResponseEntity>

MainActivity.kt

@OnClick(R.id.tv_main)
    fun getTopMovie() {
        val retrofit = Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl("http://gank.io/api/data/")
                .build()

        val apiService = retrofit.create(ApiServer::class.java)
        val listParam = listOf("0","1")
        val call = apiService.getTopMovie(listParam)
        call.enqueue(object : Callback<ResponseEntity> {
            override fun onFailure(call: Call<ResponseEntity>?, t: Throwable?) {

            }

            override fun onResponse(call: Call<ResponseEntity>?, response: Response<ResponseEntity>?) {
                Log.i("qfxl", "response = ${response?.body()}")
            }

        })
    }

@Path

如果请求的相对地址也是需要调用方传递,那么可以使用@Path注解
@Path可以用于任何请求方式,包括Post,Put,Delete等等
如:http://gank.io/api/data/Android/10/1
ApiServer.kt

@GET("Android/{pageSize}/{page}")
fun getAndroid(@Path("pageSize") pageSize: Int, @Path("page") page: Int): Call<ResponseEntity>

MainActivity.kt

@OnClick(R.id.tv_main)
    fun getAndroid() {
        val retrofit = Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl("http://gank.io/api/data/")
                .build()

        val apiService = retrofit.create(ApiServer::class.java)
        val call = apiService.getAndroid(10, 1)
        call.enqueue(object : Callback<ResponseEntity> {
            override fun onFailure(call: Call<ResponseEntity>?, t: Throwable?) {

            }
            override fun onResponse(call: Call<ResponseEntity>?, response: Response<ResponseEntity>?) {
                Log.i("qfxl", "response = ${response?.body()}")
            }

        })
    }

#Post请求

@Field

Post请求需要把请求参数放置在请求体中,而非拼接在url后面。
如:https://gank.io/api/add2gank

字段描述备注
url想要提交的网页地址
desc对干货内容的描述单独的文字描述
who提交者 ID干货提交者的网络 ID
type干货类型可选参数: Android、iOS、休息视频、福利、拓展资源、前端、瞎推荐、App
debug当前提交为测试数据如果想要测试数据请设置 debug 为 true! 可选参数: true、false

ApiServer.kt

@FormUrlEncoded
@POST("add2gank")
fun addToGank(@Field("url") url: String, @Field("desc") desc: String, @Field("who") who: String, @Field("type") type: String, @Field("debug") debug: Boolean): Call<ResponseEntity>

MainActivity.kt

 @OnClick(R.id.tv_main)
 fun addToGank() {
        val retrofit = Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl("https://gank.io/api/")
                .build()
        val apiService = retrofit.create(ApiServer::class.java)
        val call = apiService.addToGank("http://gank.io/api", "test", "qfxl", "App", true)
        call.enqueue(object : Callback<ResponseEntity> {
            override fun onFailure(call: Call<ResponseEntity>?, t: Throwable?) {

            }
            override fun onResponse(call: Call<ResponseEntity>?, response: Response<ResponseEntity>?) {
                Log.i("qfxl", "response = ${response?.body()}")
            }

        })
    }

注:@FormUrlEncoded将会自动将请求参数的类型调整为application/x-www-form-urlencoded
Field注解将每一个请求参数都存放至请求体中,还可以添加encoded参数,该参数为boolean型,encoded参数为true的话,key-value-pair将会被编码,即将中文和特殊字符进行编码转换
如:

@FormUrlEncoded
@POST("add2gank")
fun addToGank(@Field("url", encoded = true) url: String):Call<ResponseEntity>

@FieldMap

假如有多个请求参数,这个时候就可以用FieldMap
如:https://gank.io/api/add2gank

字段描述备注
url想要提交的网页地址
desc对干货内容的描述单独的文字描述
who提交者 ID干货提交者的网络 ID
type干货类型可选参数: Android、iOS、休息视频、福利、拓展资源、前端、瞎推荐、App
debug当前提交为测试数据如果想要测试数据请设置 debug 为 true! 可选参数: true、false

ApiServer.kt

@FormUrlEncoded
    @POST("add2gank")
    fun addToGank(@FieldMap mapParam: Map<String, String>, @Field("debug") debug: Boolean): Call<ResponseEntity>

MainActivity.kt

 @OnClick(R.id.tv_main)
    fun addToGank() {
        val retrofit = Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl("https://gank.io/api/")
                .build()

        val apiService = retrofit.create(ApiServer::class.java)
        val mapParam = mapOf(
                "url" to "http://gank.io/api",
                "desc" to "test",
                "who" to "qfxl",
                "type" to "App"
        )
        val call = apiService.addToGank(mapParam, true)
        call.enqueue(object : Callback<ResponseEntity> {
            override fun onFailure(call: Call<ResponseEntity>?, t: Throwable?) {

            }
            override fun onResponse(call: Call<ResponseEntity>?, response: Response<ResponseEntity>?) {
                Log.i("qfxl", "response = ${response?.body()}")
            }

        })
    }

注意,Map泛型不接受Any(Java中的Object)

@Body

只针对Post请求,参数为json形式的时候使用

上传(带进度)

定义上传进度回调接口

interface UploadListener {
    /**
     * 上传进度
     *
     * @param progress
     * @param total
     * @param done
     */
    fun onProgress(progress: Long, total: Long, done: Boolean)
}

改造RequestBody

class ProgressRequestBody(private val mRequestBody: RequestBody, private val mUploadListener: UploadListener) : RequestBody() {
    private var mCountingSink: CountingSink? = null

    override fun contentType(): MediaType? {
        return mRequestBody.contentType()
    }

    override fun contentLength(): Long {
        try {
            return mRequestBody.contentLength()
        } catch (e: IOException) {
            e.printStackTrace()
            return -1
        }

    }

    @Throws(IOException::class)
    override fun writeTo(sink: BufferedSink) {
        val bufferedSink: BufferedSink

        mCountingSink = CountingSink(sink)
        bufferedSink = Okio.buffer(mCountingSink!!)

        mRequestBody.writeTo(bufferedSink)
        bufferedSink.flush()
    }

    internal inner class CountingSink(delegate: Sink) : ForwardingSink(delegate) {

        private var bytesWritten: Long = 0

        @Throws(IOException::class)
        override fun write(source: Buffer, byteCount: Long) {
            super.write(source, byteCount)
            bytesWritten += byteCount
            mUploadListener.onProgress(bytesWritten, contentLength(), bytesWritten == contentLength())
        }
    }
}

定义上传api

interface UploadApi {
    @Multipart
    @POST
    fun upload(@Url url: String, @Part parts: List<MultipartBody.Part>): Call<ResponseBody>
}

定义拦截器

class UploadInterceptor(private val uploadListener: UploadListener) : Interceptor {

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val originRequest = chain.request()
        if (null == originRequest.body()) {
            return chain.proceed(originRequest)
        }
        val newRequest = originRequest.newBuilder()
                .method(originRequest.method(), ProgressRequestBody(originRequest.body()!!, uploadListener))
                .build()
        return chain.proceed(newRequest)
    }
}

封装上传

class ZbyUploadManager private constructor() {
    private var mRetrofit: Retrofit? = null
    /**
     * 占位BaseUrl
     */
    private val ZBY_CORP = "http://www.zbycorp.com/"
    /**
     * okHttp的拦截器
     */
    private val interceptors = SparseArray<Interceptor>()

    private var uploadListener: UploadListener? = null
    /**
     * 线程调度
     */
    private val dispatchHandler: Handler

    /**
     * 默认的Retrofit
     *
     * @return
     */
    private val defaultRetrofit: Retrofit
        get() = Retrofit.Builder()
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(ZBY_CORP)
                .client(defaultOkHttp)
                .build()

    /**
     * 默认的okHttpClient
     *
     * @return
     */
    //添加拦截器
    val defaultOkHttp: OkHttpClient
        get() {
            val builder = OkHttpClient.Builder()
            builder.readTimeout(3, TimeUnit.MINUTES)
                    .writeTimeout(3, TimeUnit.MINUTES)
                    .addInterceptor(UploadInterceptor(object : UploadListener {
                        override fun onProgress(progress: Long, total: Long, done: Boolean) {
                            val msg = Message.obtain()
                            msg.arg1 = progress.toInt()
                            msg.arg2 = total.toInt()
                            msg.obj = done
                            dispatchHandler.sendMessage(msg)
                        }

                    }))
            if (interceptorSize > 0) {
                for (i in 0 until interceptorSize) {
                    builder.addInterceptor(interceptors.get(i))
                }
            }
            return builder.build()
        }

    /**
     * 获取Retrofit
     *
     * @return
     */
    /**
     * 设置Retrofit(如果有特殊需求的话)
     *
     * @param retrofit
     */
    var retrofit: Retrofit?
        get() = if (mRetrofit == null) {
            defaultRetrofit
        } else mRetrofit
        set(retrofit) = if (retrofit == null) {
            mRetrofit = defaultRetrofit
        } else {
            mRetrofit = retrofit
        }

    /**
     * 获取拦截器数量
     *
     * @return
     */
    private val interceptorSize: Int
        get() = interceptors.size()

    init {
        dispatchHandler = Handler(Looper.getMainLooper(), Handler.Callback { msg ->
            val progress = msg.arg1.toLong()
            val total = msg.arg2.toLong()
            val done = msg.obj as Boolean
            if (uploadListener != null) {
                //如果需要转换成100进度的话(100 * progress) / total
                uploadListener!!.onProgress(progress, total, done)
            }
            true
        })
    }

    private object Holder {
        val INSTANCE = ZbyUploadManager()
    }

    /**
     * 添加拦截器
     *
     * @param interceptor
     */
    fun addInterceptor(interceptor: Interceptor) {
        interceptors.put(interceptorSize, interceptor)
    }

    /**
     * 清空所有拦截器
     */
    fun clearInterceptors() {
        interceptors.clear()
    }

    /**
     * 移除指定拦截器
     *
     * @param key
     */
    fun clearInterceptorAt(key: Int) {
        interceptors.removeAt(key)
    }

    /**
     * 上传
     *
     * @param url
     * @param uploadParams
     */
    fun upload(url: String, uploadParams: UploadParams, callback: Callback<ResponseBody>) {
        val uploadApi = retrofit?.create(UploadApi::class.java)
        val builder = MultipartBody.Builder()
        for (entry in uploadParams.entries) {
            if (entry.value is String) {
                builder.addFormDataPart(entry.key, entry.value)
            } else if (entry.value is File) {
                val file = entry.value
                builder.addFormDataPart(entry.key, file.name, RequestBody.create(MediaType.parse("multipart/form-data"), file))
            }
        }

        val body = builder.build()
        uploadApi?.upload(url, body.parts())
                ?.enqueue(callback)
    }


    /**
     * 上传带进度带回调
     *
     * @param url
     * @param uploadParams
     * @param uploadListener
     * @param callback
     */
    fun upload(url: String, uploadParams: UploadParams, uploadListener: UploadListener, callback: Callback<ResponseBody>) {
        this.uploadListener = uploadListener
        val uploadApi = retrofit?.create(UploadApi::class.java)
        val builder = MultipartBody.Builder()
        for (entry in uploadParams.entries) {
            if (entry.value is String) {
                builder.addFormDataPart(entry.key, entry.value)
            } else if (entry.value is File) {
                val file = entry.value
                builder.addFormDataPart(entry.key, file.name, RequestBody.create(MediaType.parse("multipart/form-data"), file))
            }
        }

        val body = builder.build()
        uploadApi?.upload(url, body.parts())
                ?.enqueue(callback)
    }

    companion object {

        fun get(): ZbyUploadManager {
            return Holder.INSTANCE
        }
    }
}

##UploadParams

class UploadParams {

    val entries = ArrayList<Entry>()

    fun put(key: String, value: Any) {
        entries.add(Entry(key, value))
    }

    inner class Entry(val key: String, val value: Any)
}

下载(带进度)

定义进度回调接口

interface ProgressListener {
    /**
     * 进度监听
     *
     * @param progress 当前上传下载字节数
     * @param total    总的字节数
     * @param done     是否完成
     */
    fun onProgress(progress: Long, total: Long, done: Boolean)
}

改造ResponseBody

class ProgressResponseBody(private val responseBody: ResponseBody, private val progressListener: ProgressListener) : ResponseBody() {
    private var bufferedSource: BufferedSource? = null

    override fun contentType(): MediaType? {
        return responseBody.contentType()
    }

    override fun contentLength(): Long {
        return responseBody.contentLength()
    }

    override fun source(): BufferedSource? {
        if (bufferedSource == null) {
            bufferedSource = Okio.buffer(source(responseBody.source()))
        }
        return bufferedSource
    }

    private fun source(source: Source): Source {
        return object : ForwardingSource(source) {
            internal var totalBytesRead = 0L

            @Throws(IOException::class)
            override fun read(sink: Buffer, byteCount: Long): Long {
                val bytesRead = super.read(sink, byteCount)
                totalBytesRead += if (bytesRead != -1L) bytesRead else 0
                progressListener.onProgress(totalBytesRead, responseBody.contentLength(), bytesRead == -1L)
                return bytesRead
            }
        }
    }
}

定义下载API

interface DownloadApi {
    /**
     * 下载
     *
     * @param url 下载的url
     * @return
     */
    @GET
    fun download(@Url url: String): Call<ResponseBody>
}

下载并保存到本地

class DownloadManager {
    private val TAG = DownloadManager::class.java.simpleName
    private var mRetrofit: Retrofit? = null
    /**
     * 进度监听
     */
    private var mProgressListener: ProgressListener? = null
    /**
     * 占位BaseUrl
     */
    private val ZBY_CORP = "http://www.zbycorp.com/"
    /**
     * 线程调度
     */
    private val dispatchHandler: Handler
    /**
     * okHttp的拦截器
     */
    private val interceptors = SparseArray<Interceptor>()
    /**
     * 下载回调
     */
    var onDownloadListener: OnDownloadListener? = null
    /**
     * 默认的Retrofit
     *
     * @return
     */
    private val defaultRetrofit: Retrofit
        get() = Retrofit.Builder()
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(ZBY_CORP)
                .client(defaultOkHttp)
                .build()

    /**
     * 获取拦截器数量
     *
     * @return
     */
    private val interceptorSize: Int
        get() = interceptors.size()

    /**
     * 默认的okHttpClient
     *
     * @return
     */
    //将进度回调到主线程
    //添加拦截器
    val defaultOkHttp: OkHttpClient
        get() {
            val builder = OkHttpClient.Builder()
            builder.readTimeout(3, TimeUnit.MINUTES)
                    .writeTimeout(3, TimeUnit.MINUTES)
                    .networkInterceptors()
                    .add(Interceptor { chain ->
                        val originalResponse = chain.proceed(chain.request())
                        originalResponse.newBuilder().body(
                                ProgressResponseBody(originalResponse.body()!!, object : ProgressListener {
                                    override fun onProgress(progress: Long, total: Long, done: Boolean) {
                                        val msg = Message.obtain()
                                        msg.arg1 = progress.toInt()
                                        msg.arg2 = total.toInt()
                                        msg.obj = done
                                        dispatchHandler.sendMessage(msg)
                                    }

                                })).build()
                    })
            if (interceptorSize > 0) {
                for (i in 0 until interceptorSize) {
                    builder.addInterceptor(interceptors.get(i))
                }
            }
            return builder.build()
        }

    /**
     * 获取Retrofit
     *
     * @return
     */
    /**
     * 设置Retrofit(如果有特殊需求的话)
     *
     * @param retrofit
     */
    var retrofit: Retrofit?
        get() = if (mRetrofit == null) {
            defaultRetrofit
        } else mRetrofit
        set(retrofit) = if (retrofit == null) {
            mRetrofit = defaultRetrofit
        } else {
            mRetrofit = retrofit
        }

    init {
        dispatchHandler = Handler(Looper.getMainLooper(), Handler.Callback { msg ->
            val progress = msg.arg1.toLong()
            val total = msg.arg2.toLong()
            val done = msg.obj as Boolean
            if (mProgressListener != null) {
                //如果需要转换成100进度的话(100 * progress) / total
                mProgressListener!!.onProgress(progress, total, done)
            }
            true
        })
    }

    /**
     * 添加拦截器
     *
     * @param interceptor
     */
    fun addInterceptor(interceptor: Interceptor) {
        interceptors.put(interceptorSize, interceptor)
    }

    /**
     * 清空所有拦截器
     */
    fun clearInterceptors() {
        interceptors.clear()
    }

    /**
     * 移除指定拦截器
     *
     * @param key
     */
    fun removeInterceptorAt(key: Int) {
        interceptors.removeAt(key)
    }

    /**
     * 下载带进度
     *
     * @param url              下载的url
     * @param progressListener 进度监听
     * @param destFile         存储目标文件
     */
    fun download(url: String, progressListener: ProgressListener, destFile: File?) {
        mProgressListener = progressListener
        val downloadApi = retrofit!!.create(DownloadApi::class.java)
        downloadApi.download(url)
                .enqueue(object : Callback<ResponseBody> {
                    override fun onResponse(call: retrofit2.Call<ResponseBody>, response: Response<ResponseBody>) {
                        saveFileToLocal(destFile, response.body())
                        onDownloadListener?.onDownloadSuccess(destFile!!)
                    }

                    override fun onFailure(call: retrofit2.Call<ResponseBody>, t: Throwable) {
                        onDownloadListener?.onDownloadFailed(t.message!!)
                    }
                })
    }

    /**
     * 下载不带进度
     *
     * @param url      下载的url
     * @param destFile 存储目标文件
     */
    fun download(url: String, destFile: File?) {
        val downloadApi = retrofit!!.create(DownloadApi::class.java)
        downloadApi.download(url)
                .enqueue(object : Callback<ResponseBody> {
                    override fun onResponse(call: retrofit2.Call<ResponseBody>, response: Response<ResponseBody>) {
                        saveFileToLocal(destFile, response.body())
                        onDownloadListener?.onDownloadSuccess(destFile!!)
                    }

                    override fun onFailure(call: retrofit2.Call<ResponseBody>, t: Throwable) {
                        onDownloadListener?.onDownloadFailed(t.message!!)
                    }
                })
    }

    /**
     * 保存文件到本地
     *
     * @param destFile     目标文件
     * @param responseBody 响应体
     */
    private fun saveFileToLocal(destFile: File?, responseBody: ResponseBody?) {
        if (responseBody != null && destFile != null) {
            val ins = responseBody.byteStream()
            destFile.writeBytes(ins.readBytes())
            ins.close()
        }
    }

    interface OnDownloadListener {
        /**
         * 下载成功回调
         */
        fun onDownloadSuccess(file: File)

        /**
         * 下载失败回调
         */
        fun onDownloadFailed(errorMsg: String)
    }
}

使用

val downloadManager = ZbyDownloadManager()
downloadManager.setOnDownloadListener(object : ZbyDownloadManager.OnDownloadListener {
            override fun downloadSuccess(destFile: File) {
              
            }

            override fun downloadFailed(errorMsg: String) {
          
            }
        })
        val destFileFolder = File(Environment.getExternalStorageDirectory(), "apks")
        if (!destFileFolder.exists()) {
            destFileFolder.mkdirs()
        }
        val destFile = File(destFileFolder, "iWMS.apk")
        downloadManager.download("http://192.168.8.104:8080/apks/iwms.apk", { progress, total, done ->
            updateDialog?.setProgress(((100 * progress) / total).toInt())            
        }, destFile)

参数加密

加密规则
所有请求添加公用参数如下:

client_id=android
ts=时间戳
dev=imei
req_id=uuid
sign=所有参数(不包含sign参数)按key自然升序排序,然后拼接kv(如:a1b2c3),1次md5,全部转大写,最后1次md5
MD5(UPPER(MD5(a1b2c3client_idandroiddevuuidts1234567890)))

java代码如下(晚点改为kotlin)


public class AddParamsInterceptor implements Interceptor {
    /**
     * 公用参数
     */
    private Map<String, String> commonParams = new ArrayMap<>();
    private Context context;

    public AddParamsInterceptor(Context context) {
        String timestamp = String.valueOf(TimeUtils.getServerCurrentTimeMillis());
        String imei = CommonUtil.isEmpty(DeviceUuidFactory.getInstance()
                .getIMEI(context)) ? "" : DeviceUuidFactory.getInstance()
                .getIMEI(context);
        commonParams.put("client_id", "android_mobile");
        commonParams.put("ts", timestamp);
        commonParams.put("dev", imei);
        commonParams.put("req_id", DeviceUuidFactory.getInstance()
                .getDeviceUuidString(context));
        this.context = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request orgRequest = chain.request();
        RequestBody body = orgRequest.body();
        String accessToken = (String) SpUtil.get(context, SpUtil.FILE_USER, SpUtil.KEY_USER_ACCESS_TOKEN, "");
        //收集请求参数,最后用于sign签名
        StringBuilder paramsBuilder = new StringBuilder();
        if (body != null) {
            RequestBody newBody = null;
            if (body instanceof FormBody) {
                newBody = addParamsToFormBody((FormBody) body, paramsBuilder);
            } else if (body instanceof MultipartBody) {
                newBody = addParamsToMultipartBody((MultipartBody) body, paramsBuilder);
            }
            if (null != newBody) {
                Request.Builder requestBuilder = orgRequest.newBuilder();
                //添加authorization
                if (!TextUtils.isEmpty(accessToken)) {
                    requestBuilder.addHeader("Authorization", accessToken);
                }
                requestBuilder.url(orgRequest.url())
                        .method(orgRequest.method(), newBody)
                        .build();
                return chain.proceed(requestBuilder.build());
            }
        } else {
            if (!TextUtils.isEmpty(orgRequest.method()) && "get".equals(orgRequest.method().toLowerCase())) {
                HttpUrl.Builder authorizedUrlBuilder = orgRequest.url()
                        .newBuilder()
                        .scheme(orgRequest.url().scheme())
                        .host(orgRequest.url().host());
                if (commonParams == null || commonParams.size() == 0) {
                    return chain.proceed(orgRequest);
                }
                Iterator iter = commonParams.entrySet().iterator();
                List<String> keyList = new ArrayList<>();
                ArrayMap<String, String> paramMap = new ArrayMap<>();
                //公用参数
                while (iter.hasNext()) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    keyList.add(entry.getKey().toString());
                    paramMap.put(entry.getKey().toString(), entry.getValue().toString());
                }
                //原始参数
                int originParamsSize = orgRequest.url().queryParameterNames().size();
                for (int i = 0; i < originParamsSize; i++) {
                    String key = orgRequest.url().queryParameterName(i);
                    String value = orgRequest.url().queryParameter(key);
                    keyList.add(key);
                    paramMap.put(key, value);
                }

                Collections.sort(keyList);
                int keySize = keyList.size();
                //添加公用参数
                for (int i = 0; i < keySize; i++) {
                    //防止重复添加k=v
                    if (TextUtils.isEmpty(orgRequest.url().queryParameter(keyList.get(i)))) {
                        authorizedUrlBuilder.addQueryParameter(keyList.get(i), paramMap.get(keyList.get(i)));
                    }
                    paramsBuilder.append(keyList.get(i))
                            .append(paramMap.get(keyList.get(i)));
                }
                //所有参数的k=v
                String originParamStr = paramsBuilder.toString();
                String md5Sign = CommonUtil.getMD5(CommonUtil.getMD5(originParamStr)
                        .toUpperCase());
                authorizedUrlBuilder.addQueryParameter("sign", md5Sign);
                // 新的请求
                Request.Builder requestBuilder = orgRequest.newBuilder();
                //添加authorization
                if (!TextUtils.isEmpty(accessToken)) {
                    requestBuilder.addHeader("Authorization", accessToken);
                }
                requestBuilder.method(orgRequest.method(), orgRequest.body())
                        .url(authorizedUrlBuilder.build())
                        .build();
                return chain.proceed(requestBuilder.build());
            }
        }
        return chain.proceed(orgRequest);
    }

    /**
     * 为MultipartBody类型请求体添加参数
     *
     * @param body
     * @param paramsBuilder
     * @return
     */
    private MultipartBody addParamsToMultipartBody(MultipartBody body, StringBuilder paramsBuilder) {
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        List<String> keyList = new ArrayList<>();
        ArrayMap<String, String> paramsMap = new ArrayMap<>();
        //动态添加新的参数
        if (commonParams == null || commonParams.size() == 0) {
            return builder.build();
        }
        Iterator iter = commonParams.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            keyList.add(entry.getKey().toString());
            paramsMap.put(entry.getKey().toString(), entry.getValue().toString());
        }
        Collections.sort(keyList);
        int keySize = keyList.size();
        for (int i = 0; i < keySize; i++) {
            builder.addFormDataPart(keyList.get(i), paramsMap.get(keyList.get(i)));
            paramsBuilder.append(keyList.get(i))
                    .append(paramsMap.get(keyList.get(i)));
        }
        //所有参数的k=v
        String originParamStr = paramsBuilder.toString();
        String md5Sign = CommonUtil.getMD5(CommonUtil.getMD5(originParamStr)
                .toUpperCase());
        //添加sign
        builder.addFormDataPart("sign", md5Sign);
        //添加原请求体
        for (int i = 0; i < body.size(); i++) {
            builder.addPart(body.part(i));
        }
        return builder.build();
    }

    /**
     * 为FormBody类型请求体添加参数
     *
     * @param body
     * @param paramsBuilder
     * @return
     */
    private FormBody addParamsToFormBody(FormBody body, StringBuilder paramsBuilder) {
        FormBody.Builder builder = new FormBody.Builder();
        //动态添加新的参数
        if (commonParams == null || commonParams.size() == 0) {
            return builder.build();
        }
        Iterator iter = commonParams.entrySet().iterator();
        List<String> keyList = new ArrayList<>();
        ArrayMap<String, String> paramsMap = new ArrayMap<>();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            keyList.add(entry.getKey().toString());
            paramsMap.put(entry.getKey().toString(), entry.getValue().toString());
        }
        //添加原请求体
        for (int i = 0; i < body.size(); i++) {
            keyList.add(body.encodedName(i));
            paramsMap.put(body.encodedName(i), body.encodedValue(i));
        }
        Collections.sort(keyList);
        int keySize = keyList.size();
        for (int i = 0; i < keySize; i++) {
            builder.addEncoded(keyList.get(i), paramsMap.get(keyList.get(i)));
            paramsBuilder.append(keyList.get(i))
                    .append(paramsMap.get(keyList.get(i)));
        }
        //所有请求参数的k=v
        String originParamStr = paramsBuilder.toString();
        String md5Sign = CommonUtil.getMD5(CommonUtil.getMD5(originParamStr)
                .toUpperCase());
        builder.addEncoded("sign", md5Sign);
        return builder.build();
    }
    
}

最后添加到okHttp的拦截器中。

okHttpClientBuilder.addInterceptor(new AddParamsInterceptor(context));
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值