Обработка нескольких динамических типов данных в JSON - PullRequest
0 голосов
/ 07 февраля 2019

Вот мой пример JSON, когда пользователь успешно проходит аутентификацию

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

И когда учетные данные пользователя неверны

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

Обратите внимание на изменение типов данных message & data,Используя модифицированную подгонку с этим, я получил лирическую ошибку Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

Чтобы решить эту проблему, я следовал этому примеру, чтобы решить проблему.Который решил проблему OBJECT / ARRAY.

У меня есть 3 модели LoginResponse, MessageResponse, DataResponse, и вот как я пытаюсь получить доступ к MessageResponse & DataResponse

Я не уверен, смогу ли я вообще использовать 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.

Кроме того, переключение в обратном порядке .addConverterFactory иногда вызывает сбой при доступе к LoginResponse модель

1 Ответ

0 голосов
/ 07 февраля 2019

У вас есть доступ к сетевым ошибкам и кодам ответов ?.Таким образом, вы можете создать оператор switch, который явно определяет способ десериализации ЛЮБОГО ответа

Например,

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;}}

Примечание. Приведенный выше код не был протестирован.

========================================= БИТ РЕШЕНИЯ РЕШЕНИЯ ДЕЙСТВИТЕЛЬНО =============================================================================

Основываясь на нашем разговоре и моих наблюдениях как об успехе, так и об ошибке, я имеюэто не проверенный код / ​​предложение:

    //in the retrofit response callback, get the status via JSONObject

JSONObject status = new JSONObject(response.toString()); throws Exception
String statusString = status.optString("status");

//now take the result of the string to a switch statement

Gson switchToDeserialise(String statusString){
///from what you've shown in the success & failure responses, status is either success or error, so...

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

switch(statusString){

case "success":
return new GsonBuilder().setLenient().registerTypeAdapter(LoginResponse.class, new DataDeserializer()).create();
case "error":
return new GsonBuilder().setLenient().registerTypeAdapter(LoginResponse.class, new MessageDeserializer()).create();
default:
return deserializer;

}

}
...