我在使用API调用后使用retrofit2来处理http请求。让我解释一下。
我创建了 2 java类(POJO)来处理分别为User.java
和Lecturer.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"
}
]
}
我可以使用Lecturer.java
类来处理它。
但问题是,如果响应包含单个json上的用户和讲师数据,如何处理? 。以下是请求的示例:
{
"users": [
{
"user_id": "28",
"user_email": "john@abc.com",
"user_password": "123",
"lecturer_id": "3",
"lecturer_name": "johny2"
}
]
}
要解决这个问题,我想我需要创建另一个包含User
和Lecturer
类的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 );
}
赞赏任何帮助。如果以上用例确实不够清楚,请向我索取更多输入。感谢
答案 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的字段