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));