Retrofit2处理包含两个模型数据的JSON响应

时间:2016-06-24 23:11:26

标签: java android json retrofit2

我在使用API​​调用后使用retrofit2来处理http请求。让我解释一下。

我创建了 2 java类(POJO)来处理分别为User.javaLecturer.java的用户和讲师数据。对于响应数据,例如:

{
  "users": [
    {
      "user_id": "28",
      "user_email": "john@abc.com",
      "user_password": "123"
    }
  ]
}

我可以使用User.java类来处理此响应。此文件中没有任何复杂内容,仅包含gettersetter方法。讲师数据也是如此,这里是讲师数据的例子:

{
  "lecturers": [
    {
      "lecturer_id": "3",
      "user_id": "28",
      "lecturer_name": "johny2"
    }
  ]
}

我可以使用Lecturer.java类来处理它。

但问题是,如果响应包含单个json上的用户和讲师数据,如何处理? 。以下是请求的示例:

{
  "users": [
    {
      "user_id": "28",
      "user_email": "john@abc.com",
      "user_password": "123",
      "lecturer_id": "3",
      "lecturer_name": "johny2"
    }
  ]
}

要解决这个问题,我想我需要创建另一个包含UserLecturer类的java类,不幸的是在这里我被卡住了。

这是新文件,我尝试创建(Userlecturer.java)

public class UserLecturer {

  User user;
  Lecturer lecturer;

  // how to implement on this part
}

这是UserLecturer界面:

public interface UserLecturerInterface {

  @GET ( "api/endpoint/here" )
  Call<UserLecturer> getLecturerByUserId (@Path( "userId" ) String userId );

}

赞赏任何帮助。如果以上用例确实不够清楚,请向我索取更多输入。感谢

4 个答案:

答案 0 :(得分:3)

我认为POJO应该是:

public class Users {
    String userId;
    String userEmail;
    String userPassword;
    String lecturerId;
    String lecturerName;
}

即使JSON中有2个模型,您只需要1个模型进行Retrofit。

如果您确实想要将1 JSON响应拆分为2个模型,我认为您必须实现自定义JSON转换器。

Gson gson = new GsonBuilder()
            .registerTypeAdapter(UserLecture.class, new JsonDeserializer<UserLecture>() {
                public UserLecture deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                    JsonArray usersJsonArray = json.getAsJsonObject().getAsJsonArray("users");
                    JsonObject userJsonObject = usersJsonArray.getAsJsonArray().get(0).getAsJsonObject();
                    User user = new User();
                    user.setUserId(userJsonObject.get("user_id").getAsString());
                    user.setUserEmail(userJsonObject.get("user_email").getAsString());
                    user.setUserPassword(userJsonObject.get("user_password").getAsString());
                    Lecturer lecturer = new Lecturer();
                    lecturer.setLecturerId(userJsonObject.get("lecturer_id").getAsString());
                    lecturer.setLecturerName(userJsonObject.get("lecturer_name").getAsString());
                    return new UserLecture(lecturer, user);
                }
            })
            .create();

Retrofit retrofit = new Retrofit.Builder()
.baseUrl([YOUR_BASE_URL])
.addConverterFactory(GsonFactoryConverter.create(gson))
.build();

答案 1 :(得分:2)

这是我用来将long转换为Java Date对象的一些代码。 据推测,您可以为UserLecture对象执行相同的操作。您应该能够为User和Lecture提取单个json对象,创建一个新的UserLecture对象,并将User和Lecture作为对象包含在其中。

Gson gson = new GsonBuilder().registerTypeAdapter(UserLecture.class, new JsonDeserializer<UserLecture>() {
            public UserLecture deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                JsonObject user = json.getAsJsonObject().getAsJsonObject("user");
                JsonObject lecture = json.getAsJsonObject().getAsJsonObject("lecture");
                return new UserLecture(user, lecture);
            }
        }).create();

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com")
    .addConverterFactory(GsonFactoryConverter.create(gson))
    .build();

然后在UserLecture内:

public UserLecture(JsonObject userJson, JsonObject lectureJson) {
   this.user = new User();
   this.user.setUserId(userJson.get("user_id").getAsInt());
   this.user.serUserEmail(userJson.get("user_email").getAsString());
   //so on.
}

答案 2 :(得分:1)

首先让我说你需要在这里处理的JSON被设计破坏,所以你应该敦促那个人/部门/公司来解决它。

其次,像Jackson这样的JSON处理器允许轻松地解析这样的多态数据结构,但是它们需要某种type标志来区分另一种类型(即type: "user"和{ {1}})。没有这样的type: "lecturer"标志,还有一种方法可以做到这一点,但还有更多的手工工作。 last example here显示了如何操作。

答案 3 :(得分:0)

是的,这是一种可能的解决方案。 Gson忽略所有字段,这些字段与@SerializedName注释不匹配。因此,您可以尝试另一种解决方案而不创建任何更多的pojo类 - 将结果返回为String,并尝试将此字符串解析为两个类。如果一个结果是空的 - 那么你有另一个结果。但是,如果两个kbject都不为空 - 那么原始响应包含来自两个pojos的字段