【问题标题】:Handling different Retrofit responses处理不同的改造响应
【发布时间】:2020-09-15 02:24:47
【问题描述】:

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

问题...

我从我的网络服务中收到以下答案之一,具体取决于是否创建了某个用户:

{
    "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 中显示如下内容:

好的, 编号: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();
}

正如我上面提到的,我想当Call 被执行时,我得到的响应是Map&lt;String, List&gt;,但我不知道如何处理这个,所以我可以得到我想要的值希望:

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 的结构

提前致谢!!

【问题讨论】:

    标签: java android gson retrofit2


    【解决方案1】:

    你可以使用简单的方法而不是解析成Map&lt;String, List&gt;

    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
    }
    

    【讨论】:

    • 非常好,非常感谢!但是我现在如何定义它对应类的对象呢?我试过这个EntityUsr usr = gson.fromJson(response.body().toString(), EntityUsr.class); 但显然不起作用。我应该传递或使用string,还是应该使用fromJson 方法?
    • 您还想让您的解决方案正常工作吗?你试过我的解决方案了吗?
    • 是的,我已经尝试过并且可以完美地识别来自 web 服务的响应,儿子现在我的问题是创建对象,但无法弄清楚如何......我试图理解response 正如定义的那样,是 EntityXXX 的 ArrayList,因此,该对象已经以某种方式创建,只需将值传递给它的实例...¿?
    • 确保改造已经成为您的实体。因为您已经设置了工厂 addConverterFactory(GsonConverterFactory.create(gson))
    • 是的,工作得很好!!我已经浏览了对象及其方法,直到我到达对象本身的方法 response.body().getUser().get(0).getUsername() 非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 2021-12-21
    • 2018-12-16
    • 2018-05-26
    • 1970-01-01
    • 2016-10-06
    • 2014-04-18
    • 2020-06-17
    • 1970-01-01
    相关资源
    最近更新 更多