我当前在我的Android项目中使用Retrofit 2.3,并且最近我们使用的API已更新,因此在所有POST请求中,JSON正文中都必须包含"version":number
。假设我们需要传递UserCredentials对象-之前的请求主体只是使用GSON转换器序列化了,看起来像这样
{"username":"myUsername", "password":"myPassword"}
现在它必须具有其他“版本”字段:
{"username":"myUsername", "password":"myPassword", "version":1}
我已经搜索了几个小时,如何设置自定义转换器工厂以进行改装,但是我发现的全部是如何从序列化中排除某些字段。我知道我可以简单地将"version"
字段添加到我的所有POJO中,但是我发现这种方法“肮脏”,因为它将仅在向服务器发送数据期间使用。
以前有人做过这样的事吗?
答案 0 :(得分:1)
我做到了,但并非完全按照您想要的方式进行,您可以创建BaseRequest POJO类,在其中您可以使用版本号,然后将该类扩展到您正在使用的其他POJO类:
Expected Output:
OrderedDict([('108', ['0.0']), ('101', ['0.0']), ('13', ['0.0']), ('104',
['0.0']), ('105', ['0.0']), ('109', ['0.0']), ('107', ['1.0']), ('102',
['1.0']), ('106', ['1.0']), ('99', ['1.0']), ('103', ['1.0']), ('100',
['1.0']), ('14', ['8.0'])])
将此基本POJO类扩展到其他POJO类以使用这样的版本号:
class BaseRequest{
@SerializedName("version")
public int version= 0;
}
此方法有很多好处,例如,如果您在API中需要一个字段,那么就不需要更改所有api。您只需在baserequest中添加一个字段即可实现。
答案 1 :(得分:0)
使用OkHTTP客户端的自定义拦截器解决了此问题。因此,我创建了自定义拦截器,该拦截器将分析传出请求并在满足特定条件时更改其主体JSON数据。
okHttpClientBuilder.addInterceptor(CustomInterceptor(1))
像魅力一样工作!
import okhttp3.Interceptor
import okhttp3.RequestBody
import okhttp3.Response
import okio.Buffer
import org.json.JSONException
import org.json.JSONObject
import java.io.IOException
class CustomInterceptor (private val version: Int): Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val requestBody = request.body()
val subtype = requestBody?.contentType()?.subtype()
if(subtype != null
&& subtype.contains("json")) {
val bodyWithToken = addVersionParamToJSONBody(requestBody)
if(null != bodyWithToken){
val requestBuilder = request.newBuilder()
request = requestBuilder
.post(bodyWithToken)
.build()
}
}
return chain.proceed(request)
}
private fun addVersionParamToJSONBody(requestBody: RequestBody?) : RequestBody? {
val customRequest = bodyToString(requestBody)
return try{
val jsonObject = JSONObject(customRequest)
jsonObject.put("version", version)
RequestBody.create(requestBody?.contentType(), jsonObject.toString())
} catch (e: JSONException){
e.printStackTrace()
null
}
}
private fun bodyToString(requestBody: RequestBody?): String{
return try {
val buffer = Buffer()
requestBody?.writeTo(buffer)
buffer.readUtf8()
} catch (e: IOException){
e.printStackTrace()
""
}
}
}