Java 改型2处理包含两个模型数据的JSON响应

Java 改型2处理包含两个模型数据的JSON响应,java,android,json,retrofit2,Java,Android,Json,Retrofit2,在从API调用之后,我使用Reformation2处理http请求。让我解释一下 我创建了2个java classPOJO来处理用户和讲师数据,分别是user.java和讲师.java。对于响应数据,例如: { "users": [ { "user_id": "28", "user_email": "john@abc.com", "user_password": "123" } ] } 我可以使用User.java类来处理这个响应。这

在从API调用之后,我使用Reformation2处理http请求。让我解释一下

我创建了2个java classPOJO来处理用户和讲师数据,分别是user.java和讲师.java。对于响应数据,例如:

{
  "users": [
    {
      "user_id": "28",
      "user_email": "john@abc.com",
      "user_password": "123"
    }
  ]
}
我可以使用User.java类来处理这个响应。这个文件中没有复杂的内容,只包含getter和setter方法。讲师数据也是如此,以下是讲师数据的示例:

{
  "lecturers": [
    {
      "lecturer_id": "3",
      "user_id": "28",
      "lecturer_name": "johny2"
    }
  ]
}
我可以通过使用讲师.java类来处理它

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

{
  "users": [
    {
      "user_id": "28",
      "user_email": "john@abc.com",
      "user_password": "123",
      "lecturer_id": "3",
      "lecturer_name": "johny2"
    }
  ]
}
为了解决这个问题,我想我需要创建另一个java类,该类同时包含用户类和讲师类,不幸的是,在这里我被卡住了

这是我试图创建的新文件user讲师.java:

以下是用户界面:

public interface UserLecturerInterface {

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

}

谢谢你的帮助。如果上面的用例不够清晰,请询问我更多的输入。谢谢

是的,这是一种可能的解决方案。Gson忽略所有字段,这些字段的名称与@SerializedName注释不匹配。所以,您可以尝试另一种解决方案,而无需再创建任何pojo类—将结果作为字符串返回,并尝试将此字符串作为两个类进行解析。如果一个结果是空的,那么就有另一个结果。但是,如果两个K对象都不是空的,那么原始响应包含来自两个POJO的字段是的,这是一种可能的解决方案。Gson忽略所有字段,这些字段的名称与@SerializedName注释不匹配。所以,您可以尝试另一种解决方案,而无需再创建任何pojo类—将结果作为字符串返回,并尝试将此字符串作为两个类进行解析。如果一个结果是空的,那么就有另一个结果。但是,如果两个K对象都不是空的,那么原始响应包含来自两个POJO的字段,我认为POJO应该是:

public class Users {
    String userId;
    String userEmail;
    String userPassword;
    String lecturerId;
    String lecturerName;
}
尽管JSON中有2个模型,但您只需要1个模型进行改装

如果您真的想将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();

我认为POJO应该是:

public class Users {
    String userId;
    String userEmail;
    String userPassword;
    String lecturerId;
    String lecturerName;
}
尽管JSON中有2个模型,但您只需要1个模型进行改装

如果您真的想将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();

这是我用来将long转换为Java日期对象的一些代码。 大概,您可以对您的UserTarch对象执行相同的操作。您应该能够为User和teaching提取单独的json对象,创建一个新的userteaching对象,并将User和teaching作为其中的对象

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

这是我用来将long转换为Java日期对象的一些代码。 大概,您可以对您的UserTarch对象执行相同的操作。您应该能够为User和teaching提取单独的json对象,创建一个新的userteaching对象,并将User和teaching作为其中的对象

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

首先让我说,您需要在这里处理的JSON被设计破坏了,所以您应该敦促家伙/部门/公司修复它


其次,像这样的JSON处理器允许轻松解析这样的多态数据结构,但它们需要某种类型的标志来区分另一种类型,即type:user和type:讲师。也有一种方法可以在没有此类类型标志的情况下实现这一点,但是需要进行更多的手工工作。首先,让我说,您需要在这里处理的JSON被设计破坏了,因此您应该敦促家伙/部门/公司修复它


其次,像这样的JSON处理器允许轻松解析这样的多态数据结构,但它们需要某种类型的标志来区分另一种类型,即type:user和type:讲师。也有一种方法可以在没有此类类型标志的情况下实现这一点,但是需要进行更多的手工工作。显示了如何执行此操作。

因此我需要手动执行此操作,以解析来自API的响应,而不是使用POJO类。谢谢你的主意。将尝试实现它。不,您不应该手动执行。Gson解析器将自动执行此操作,但若在响应中找不到字段名,它将使用默认值。您可以尝试解析与用户和讲师classesHmm相同的响应,但事情有点混乱。你们能分享一个简单的例子吗?所以我需要手动解析来自API的响应,而不是使用POJO类。谢谢你的主意。将尝试实现它。不,您不应该手动执行。Gson解析器将自动执行此操作,但若在响应中找不到字段名,它将使用默认值。您可以尝试解析与用户和讲师classesHmm相同的响应,但事情有点混乱。你能举个简单的例子吗?我认为这是正确的解决方案。您发现了什么问题吗?@RaymondLukanta的问题是,如何在user讲师类中编写getter和setter代码,以便使这些getter可以在user2的成功回调中调用

@您只需扩展类,公共类用户扩展讲师,并重新定义api调用getCatherByUserId。但是要小心继承。@b1izzard这种情况下的继承部分不合适。。因为稍后,用户数据可能会有另一个实体混合在一起。目前,只有用户数据与讲师数据混合。稍后可能会与其他数据混合。我认为这是正确的解决方案。你发现有什么问题吗?@RaymondLukanta的问题是,如何在user讲师类中编写getter和setter代码,以便让这些getter可以调用user2的成功callback@NorlihazmeyGhazali您只需扩展类,公共类用户扩展讲师,并重新定义api调用get讲师的Yuserid。但是要小心继承。@b1izzard这种情况下的继承部分不合适。。因为稍后,用户数据可能会有另一个实体混合在一起。目前,只有用户数据与讲师数据混合。稍后可能会与其他数据混合。此POJO与讲师的数据混合。我已经分别有了用户和讲师的POJO。我想这不是我的主意。因为在之后,响应数据可能会包含另一个数据,因为我正在连接数据库中的表,以便仅根据一个请求获得结果。是的,如果讲师数据只与用户结合,那么你的想法很好使用。如果JSON结构是这样的,我认为你不能使用默认的改型JSON转换器。因此,我没有办法创建另一个包含用户和讲师的POJO类?你可以尝试下面Ali的答案。。我想那会有用的。是的,正在努力。不管怎样,谢谢你的回答。这个POJO和讲师的数据混在一起了。我已经分别有了用户和讲师的POJO。我想这不是我的主意。因为在之后,响应数据可能会包含另一个数据,因为我正在连接数据库中的表,以便仅根据一个请求获得结果。是的,如果讲师数据只与用户结合,那么你的想法很好使用。如果JSON结构是这样的,我认为你不能使用默认的改型JSON转换器。因此,我没有办法创建另一个包含用户和讲师的POJO类?你可以尝试下面Ali的答案。。我想那会有用的。是的,正在努力。不管怎样,谢谢你的回答对不起,我是新手。我应该在哪里实现上述代码?改型使用Gson或其他一些JSON库从JSON响应构建对象。请看这里的配置部分:我假设您使用了Gson,因为这是最常见的配置,因为它比Jackson的库更小。我更新了答案,以澄清如何配置Gson。注意,我没有试过这个,只是有一种感觉这应该有效。如果您声明一个对象来类型userteaching,那么应该调用这个反序列化方法来对其进行反序列化。是的,我使用gson作为转换器,所有单个响应都由转换器自动解析。但如果响应与现有POJO不匹配,则会被卡住。我了解了它的实现方式,但在这一行上出现了错误User=json.getAsJsonObject.getasjsonobjectser;用户讲座=json.getAsJsonObject.getAsJsonObject讲座;看起来像是从GetAsJSonObjectator获取的值;作为Json对象而不是用户对象返回。抱歉,我是新手。我应该在哪里实现上述代码?改型使用Gson或其他一些JSON库从JSON响应构建对象。请看这里的配置部分:我假设您使用了Gson,因为这是最常见的配置,因为它比Jackson的库更小。我更新了答案,以澄清如何配置Gson。注意,我没有试过这个,只是有一种感觉这应该有效。如果您声明一个对象来类型userteaching,那么应该调用这个反序列化方法来对其进行反序列化。是的,我使用gson作为转换器,所有单个响应都由转换器自动解析。但如果响应与现有POJO不匹配,则会被卡住。我了解了它的实现方式,但在这一行上出现了错误User=json.getAsJsonObject.getasjsonobjectser;用户讲座=json.getAsJsonObject.getAsJsonObject讲座;看起来像是从GetAsJSonObjectator获取的值;作为Json对象而不是用户对象返回。感谢您的输入。。将尝试查看Ithanks以获取输入。。我会试着看看