在JSON中处理多个动态数据类型

时间:2019-02-07 13:12:22

标签: android json gson retrofit2

当用户成功通过身份验证时,这是我的示例JSON

{
    "status": "success",
    "message": "",
    "data": {
        "_id": {
            "$id": "..."
        },
        "email": "...",
        "name": "...",
        "mobile": "...",
        "mobile_status": "...",
        "email_status": "..."
    }
}

当用户凭据错误时

{
    "status": "error",
    "message": {
        "msg": [
            "Login detail incorrect"
        ]
    },
    "data": ""
}

请注意messagedata数据类型的更改。与此配合使用,我收到了著名的错误Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

要解决此问题,我遵循了this的示例来解决此问题。确实解决了OBJECT / ARRAY问题。

我有3个型号LoginResponseMessageResponseDataResponse,这就是我试图访问MessageResponseDataResponse的方式

我不确定我是否可以使用2

Gson messageDeserializer = new GsonBuilder().setLenient().registerTypeAdapter(LoginResponse.class, new MessageDeserializer()).create();
Gson dataDeserializer = new GsonBuilder().setLenient().registerTypeAdapter(LoginResponse.class, new DataDeserializer()).create();
builder.addConverterFactory(GsonConverterFactory.create(messageDeserializer));
builder.addConverterFactory(GsonConverterFactory.create(dataDeserializer));

我认为这些自定义JsonDeserializer的工作方式不符合预期。我无法投射来自这些JsonDeserializer的返回响应。我只能以字符串形式访问它们,这甚至不是正确的JSON格式的字符串。

当我访问LoginResponse模型时,切换.addConverterFactory的顺序有时也会导致崩溃

1 个答案:

答案 0 :(得分:2)

您可以访问网络错误和响应代码吗?这样,您可以创建一个switch语句,显式定义如何反序列化任何响应

例如,

docker build -t flask-image .
docker run -d -p 5000:5000 flask-image:latest
docker logs <container_id>

注意:上面的代码尚未经过测试。

=================================真正的编辑编辑====== ================================================== =====================

根据我们的交谈以及对成功与错误响应的观察,我得到了这个未经测试的代码/建议:

Gson switchToDeserialise(int errorCode){

///i assume 200 means correct response. And 404 means there's an errorCode

Gson deserializer = new GsonBuilder().create();

switch(errorCode){
case 200:
return new GsonBuilder().setLenient().registerTypeAdapter(LoginResponse.class, new DataDeserializer()).create();
case 404:
return new GsonBuilder().setLenient().registerTypeAdapter(LoginResponse.class, new MessageDeserializer()).create();
default:
return deserializer;}}