Обработка различных ответов на модернизацию - PullRequest
0 голосов
/ 28 мая 2020

Я знаю, что этот вопрос задавали много, но ни один из ответов, которые я видел, не помог мне прояснить эту проблему. Мне нужно больше рекомендаций по моему подходу, чем конкретный ответ.

Проблема ...

Я получаю один из следующих ответов от своих веб-служб, в зависимости от того, был ли создан какой-либо пользователь:

{
    "ok": [
        {
            "id": 1,
            "username": "test",
            "pass": "123",
            "reg_date": "2020-05-27 00:00:00"
        }
    ]
}

и ...

{
    "error": [
        {
            "message": "No such user"
        }
    ]
}

Пожалуйста, поправьте меня, если я ошибаюсь в этом определении : Оба объекта с ключом String и array в качестве значения, а array, которое может иметь любую длину, в данном случае имеет тип object

Итак, мне нужно, как вы уже догадались, взять укажите значения c из этих ответов в зависимости от сценария th, даже значение key («ok» или «error»), и покажите в каком-нибудь TextView что-то вроде:

ok, id: 1

или

ошибка, такого пользователя нет

То, что я пробовал до сих пор, - это создать класс для каждого объекта внутри полученный список:

public class EntityUser {
    @SerializedName("id")
    private int id;
    @SerializedName("username")
    private String username;
    @SerializedName("pass")
    private String password;
    @SerializedName("reg_date")
    private String registerDate;

    //Getters and constructor...
}
public class EntityError {
    @SerializedName("message")
    private String message;

    //Getters and constructor...
}

И Api, где, как мне кажется, проблема:

public interface JsonApi {
    @GET("SelectUser.php")
    Call<Map<String, List>> getGenericResponse();
}

Как я уже упоминал выше, я полагаю, что что я g etting в качестве ответа - Map<String, List> при выполнении Call, но я не знаю, как это обработать, поэтому я могу получить значения, которые я sh:

Gson gson = new GsonBuilder().setLenient().create();
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://192.168.0.35/app_android/webservices/")
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

        JsonApi jsonApi = retrofit.create(JsonApi.class);
        Call<Map<String, List>> call = jsonApi.getGenericResponse();

        call.enqueue(new Callback<Map<String, List>>() {
            @Override
            public void onResponse(Call<Map<String, List>> call, Response<Map<String, List>> response) {
                if(response.isSuccessful()){
                    if (response.body().containsKey("ok")){
                         //Here i need to create instance of EntityUsr so I can bind the values to his vars
                    }if(response.body().containsKey("error")){
                        //Shows an error message according to the message value
                    }
                }
            }

            @Override
            public void onFailure(Call<Map<String, List>> call, Throwable t) {
                prueba.setText("Error: " + t.getMessage());
            }
        });

Как я писал в коде мне нужно создать экземпляр соответствующего объекта в зависимости от ответа, который response приносит от веб-службы, чтобы получить от него указанные c значения.

Как я могу это сделать ?

Я очень потерялся в своем подходе, учитывая удобство использования Retrofit?

Я не хочу изменять структуру json, полученного от веб-службы

Спасибо заранее !!

1 Ответ

2 голосов
/ 28 мая 2020

Вы можете использовать простые способы вместо синтаксического анализа Map<String, List>

  1. Объявить объект UserResponse
public class UserResponse {
    @SerializedName("ok")
    private ArrayList<EntityUser> users;
    @SerializedName("error")
    private ArrayList<EntityError> errors;
}
Измените вызов API на этот
public interface JsonApi {
    @GET("SelectUser.php")
    Call<UserResponse> getGenericResponse();
}
Обработка ответа при успешном получении
if (response.body().getUsers() != null){
   // return list users
}if(response.body().getErrors != null){
   // return list errors
}
...