处理不同的 Retrofit 响应

Handling different Retrofit responses

我知道这个问题已经被问了很多,但是 none 我看到的答案帮助我澄清了这个问题。 我需要更多关于我的方法的指南,而不是具体的答案。

问题...

我从我的网络服务收到下一个答案,具体取决于是否有用户:

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

和...

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

如果我对这个定义有误,请纠正我:两者都是以 String 作为键和 array 作为值的对象, array 可以是任意长度,在本例中,类型为 object

因此,正如您可能已经猜到的那样,我需要根据情况从该响应中获取特定值,甚至 key 值("ok" 或 "error"),以及在某些 TextView 中显示如下内容:

ok, id: 1

error, No such user

到目前为止,我一直在尝试为收到的列表中的每个对象创建一个 class:

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

正如我上面提到的,我想我得到的响应是 Map<String, List>Call 被执行时,但我不知道如何处理这个所以我可以获得我想要的值:

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 从网络服务带来的答案创建相应对象的实例,以便从中获取特定值。

我该怎么做?

考虑到 Retrofit 的可用性,我是否对自己的方法感到迷茫?

我不想更改从 webservice

收到的 json 的结构

提前致谢!!

您可以使用简单的方法而不是将其解析为 Map<String, List>

  1. 声明对象UserResponse
public class UserResponse {
    @SerializedName("ok")
    private ArrayList<EntityUser> users;
    @SerializedName("error")
    private ArrayList<EntityError> errors;
}
  1. 将您的 API 调用更改为此
public interface JsonApi {
    @GET("SelectUser.php")
    Call<UserResponse> getGenericResponse();
}
  1. 获取成功后处理响应
if (response.body().getUsers() != null){
   // return list users
}if(response.body().getErrors != null){
   // return list errors
}