【问题标题】:RxJava+Retrofit+Gson JsonSyntaxException on server error response服务器错误响应上的 RxJava+Retrofit+Gson JsonSyntaxException
【发布时间】:2018-08-09 07:51:06
【问题描述】:

我有 REST POST 调用创建订单为Observable<OrderResponse>,当订单创建调用成功时一切都很好,但是服务器返回错误我得到com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $,因为 Gson 不知道如何处理与我的字段不同的 json响应模型

服务器错误响应:

[{
    "code": 99,
    "message": "Please check your request"
}]

订单响应

data class OrderResponse(

    @Expose
    var orderId: String,

    @Expose
    var redirectUrl: String,

    @Expose
    var validUntil: Long

)

RxJava 订阅

repository.requestCreateNewOrder(newOrder)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(object : Observer<OrderResponse> {
                        override fun onComplete() {                  
                        }

                        override fun onSubscribe(d: Disposable) {
                            compositeDisposable.add(d)
                        }

                        override fun onNext(t: OrderResponse) {
                        }

                        override fun onError(t: Throwable) {
                          //HERE I GET JsonSyntaxException
                        }
                    })

改装服务

interface OrderService {
@Headers(
        "Content-Type: application/x-www-form-urlencoded ",
        "Connection: Keep-Alive",
        "Accept-Encoding: application/json",
        "User-Agent: Fiddler"
)
@FormUrlEncoded
@POST("/createOrder")
fun createOrder(@Field("orderId") orderId: String,
                @Field("payCurrency") payCurrency: String,
                @Field("payAmount") payAmount: Double,
                @Header("Content-Length") length: Int): Observable<OrderResponse>}

任何人对如何通过改造或错误模型了解如何处理有任何建议

【问题讨论】:

  • 分享您的代码以澄清问题。
  • 请粘贴您的模型类 OrderResponse
  • 从 API 分享您的 json 响应。
  • 已分享[{ "code": 99, "message": "请检查您的请求" }]
  • 服务器响应在大多数情况下是单一的/可完成的。你不需要 Observable。

标签: android kotlin retrofit2 rx-java2 gson


【解决方案1】:

当您使用 GSON 解析 JSON 时。

您的 JSON 成功响应将类似于

{
    "orderId": 1,
    "redirectUrl": "url",
    "validUntil": 12414194
}

而对于错误响应,您的 JSON 响应以 Array 开头。

[{
    "code": 99,
    "message": "Please check your request"
}]

所以告诉服务器人员不要在 Array [] 中添加错误响应。

如果您以数组形式获得响应,那么您必须使用列表。

repository.requestCreateNewOrder(newOrder)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(object : Observer<List<OrderResponse>> {
                        override fun onComplete() {                  
                        }

                        override fun onSubscribe(d: Disposable) {
                            compositeDisposable.add(d)
                        }

                        override fun onNext(t: OrderResponse) {
                        }

                        override fun onError(t: Throwable) {
                          //HERE I GET JsonSyntaxException
                        }
                    })

在观察者响应中,如果您的 JSON 响应以类似错误的数组开头,则必须添加为列表。

解决方案:从后端纠正它,因为它没有在 ARRAY 中添加错误响应。

【讨论】:

    【解决方案2】:

    根据您的代码,您只处理成功响应

    但是您也需要处理您的错误响应,为此您需要确保您的 API 应该向您发送不同于 200 的错误代码(成功响应通常大于 200 且小于 300,即代码 >= 200 && 代码

    您只需将可观察的返回类型更改为

    即可实现此目的
     Observable<Response< OrderResponse>>
    

    在收到服务器的响应后,只需检查

               if (orderResponse.isSuccessful()) {
                  //here you can handle success by using orderResponse.getbody()
                } else {
                     // here you can display error message and if you further want 
                    // to parse error response from server then use below function
                    errorOrderResponseHandling(orderResponse);
                }
    

    您想进一步将响应解析为错误模型(在此示例中,OrderAPIError 是错误响应的模型类)然后下面是函数

     private void errorOrderResponseHandling(Response<OrderResponse> orderResponse) {
            OrderAPIError orderAPIError = null;
            try {
                orderAPIError = new Gson().fromJson(String.valueOf(new 
                JSONObject(orderResponse.errorBody().string())), OrderAPIError.class);
               // further orderAPIError object you can fetch server message and display 
                it to user as per your requirement
            } catch (JSONException e) {
                e.printStackTrace();
    
            } catch (IOException e) {
                e.printStackTrace();
    
            }
        }
    

    以上示例是在 android 中而不是在 kotlin 中,但您可以在 kotlin 中获得想法并相应地使用函数

    【讨论】:

    • 进行了这些更改,但在 onError 响应代码为 203 时得到 JSON 异常
    • 您需要与服务器团队合作,因为 203 不是错误响应,正如我在回答成功响应范围为 200-299 中已经提到的那样。他们如何在上述状态代码范围内向您发送错误响应.. 要求他们更改它,然后您才能解决此问题,您需要检查状态代码 en.wikipedia.org/wiki/List_of_HTTP_status_codes
    猜你喜欢
    • 2016-10-28
    • 2020-08-03
    • 2012-10-04
    • 1970-01-01
    • 2016-03-21
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多