改造2。如果代码为200,如何处理响应内的错误JSON

时间:2018-11-18 13:57:22

标签: kotlin retrofit2 android gson

我正在使用Vk Api,在1种情况下,我得到的响应对象的代码为200,但其主体为错误JSON。

我想问你-是否有可能以某种方式从响应中获取错误对象并查看从Vk Api返回的error_code

我在Android和Retrofit 2上使用GsonConverterFactory

我正在尝试做这样的事情:

class NetworkCheckerInterceptor(val networkChecker: NetworkChecker) : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        val requestBuilder = chain.request().newBuilder()
        if (!networkChecker.isConnected()) {
            throw NoNetworkConnectionException("No network connection.")
        }
        try {
            val response =  chain.proceed(requestBuilder.build())
            val error = Gson().fromJson(response.body()?.string(), Error::class.java)
            return response
        } catch (e: SocketTimeoutException) {
            throw SocketTimeoutException()
        } catch (e: UnknownHostException) {
            throw UnknownHostException()
        }
    }
}

但是当我尝试获取“错误”对象时出现错误。

Json错误示例:

  {
  "error": {
    "error_code": 7,
    "error_msg": "Permission to perform this action is denied",
    "request_params": [
      {
        "key": "oauth",
        "value": "1"
      },
      {
        "key": "method",
        "value": "stats.get"
      },
      {
        "key": "timestamp_to",
        "value": "1542549195"
      },
      {
        "key": "month",
        "value": "month"
      },
      {
        "key": "group_id",
        "value": "56461699"
      },
      {
        "key": "v",
        "value": "5.87"
      },
      {
        "key": "interval",
        "value": "month"
      },
      {
        "key": "stats_groups",
        "value": "visitors"
      },
      {
        "key": "timestamp_from",
        "value": "1514757660"
      }
    ]
  }
}

我唯一关心的是"error_code": 7,这与许可问题有关。

那么,即使我的响应代码为200,我也如何获得该对象?

1 个答案:

答案 0 :(得分:2)

您可以为VK网络响应创建基类

abstract class BaseVkResponse<T> {
    var response: T? = null
    var error: VKError? = null // (from vk sdk)
}

,每个响应都应扩展它。例如

class NewsItem {
    var type: String? = null
    var text: String? = null
    var date: Long? = null
}

class NewsPage {
    var items: List<NewsItem>? = null
    @SerializedName("nextFrom")
    var nextFrom: String? = null
}

class NewsResponse : BaseVkResponse<NewsPage>()

和改造界面看起来像

interface VkService {
    @GET("newsfeed.getRecommended")
    fun getNews(@Query("access_token") accessToken: String,
                @Query("v") apiVersion: String,
                @Query("count") count: Int?,
                @Query("start_from") startFrom: String?): Single<NewsResponse>
}

然后注册特殊类型的适配器以解析VkError类型

internal class ErrorTypeAdapter : JsonDeserializer<VKError> {

    @Throws(JsonParseException::class)
    override fun deserialize(json: JsonElement,
                             typeOfT: Type,
                             context: JsonDeserializationContext
    ): VKError? {
        return try {
            VKError(JSONObject(json.toString()))
        } catch (e: JSONException) {
            null
        }
    }
}

val gson = GsonBuilder().apply {
    registerTypeAdapter(VKError::class.java, ErrorTypeAdapter())
}

如果响应的error字段不为空,则应根据需要进行处理。在其他情况下,您可以将其视为成功。