首页 > 解决方案 > 预期 BEGIN_ARRAY 但为 STRING,如何将 STRING 转换为空 ARRAY?

问题描述

我正在使用 Android/Java 编写一个移动应用程序,并且正在使用 Retrofit、RxJava 和 RxAndroid 执行一些 HTTP 请求。

在其中一个 HTTP 请求中,我已经声明我的模型类期望得到这样的响应:

{
   "code":201,
   "message":"Successfully",
   "data":{
      "devices":[
         {
            "state":"OK",
            // ... a few more properties
         }
      ]
   }
}

有一种情况,同一个 HTTP 请求返回不同的正文,如下所示:

{
   "code":201,
   "message":"Successfully",
   "data":{
      "devices":"" // <= is not an array anymore, it's just an empty string
   }
}

由于响应正文中的这种差异,我收到以下错误:

android 应为 BEGIN_ARRAY 但为 STRING

我正在考虑一种将空字符串转换为空数组以避免错误的方法,至少一个空数组与我的模型类匹配。

我的模型:

public class FullResponse {
    @SerializedName("code")
    private int code;
    @SerializedName("message")
    private String message;
    @SerializedName("data")
    private FullData data;

    // Constructor
    // Getters & Setters
}

public class FullData {

    private List<Device> devices;

    // Constructor
    // Getters & Setters
}

public class Device {

    private String state;
    // ... a few more properties

    // Constructor
    // Getters & Setters
}

端点接口:

public interface ApiService {

    @FormUrlEncoded
    @POST("/status.php")
    Observable<FullResponse> getStatus(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> request);

}

执行请求:

public class Request extends BaseRequest {

    private Map<String, String> requestData;
    private FullRequestSubscriber mStatusFullSubscriber;

    // Constructor

    @Override
    public void request() {
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");

        if (mStatusFullSubscriber != null) {
                apiService
                        .getStatus(headers, requestData)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(mStatusFullSubscriber);
            }

        mStatusFullSubscriber.addToCompositeSubscription();

    }
}

订户:

public class FullRequestSubscriber extends BaseSubscriber<FullResponse> {

    private FullResponse response;
    private Context mContext;
    private OnSubscriptionInteractionListener subscriptionListener;
    private OnRequestInteractionListener interactionListener;

    // Constructor

    @Override
    public void onStart() {
        this.response = null;
        super.onStart();
    }

    @Override
    public void onCompleted() {
        super.onCompleted();
        this.interactionListener.onRequestResponse(this.response);
    }

    // Error received here: android Expected BEGIN_ARRAY but was STRING
    @Override
    public void onError(Throwable e) {
        //super.onError(e);
        getSubscriberListener().removeSubscriber(this);

        if (requireLoading()) {
            ((BaseActivity) getContext()).hideLoading();
        }

        this.interactionListener.onRequestError();
    }

    @Override
    public void onNext(FullResponse o) {
        this.response = o;
    }

    @Override
    protected Context getContext() {
        return this.mContext;
    }

    @Override
    protected Class<?> getErrorResponseType() {
        return null;
    }

    @Override
    protected OnSubscriptionInteractionListener getSubscriberListener() {
        return this.subscriptionListener;
    }

    public interface OnRequestInteractionListener {
        void onRequestResponse(FullResponse data);
        void onRequestError();
    }
}

我不确定在哪里以及如何进行转换以修复错误。

我的目标是将空字符串转换为空数组以避免错误并维护匹配模型。

标签: androidretrofitrx-javarx-android

解决方案


我以前遇到过这个问题。你能控制反应吗?我发现的最佳解决方案是让 BE 发送 Null 值而不是字符串。改造很棒,但要求它有条件地转换为不同的对象类型有点恶心。

..但如果你真的想这样做,看起来你可以随心所欲地制作private List<Device> devices;private JSONObject devices;手动铸造东西。参考改造多种响应类型

编辑尝试为其设备添加一个 serializedName 到 FullData:

public class FullData {

    @SerializedName("devices")
    private List<JSONObject> devices;

    // Constructor
    // Getters & Setters
}

推荐阅读