Я пытаюсь преобразовать тело ответа http в формате JSON в объект Java с помощью библиотеки GSON, но после попытки сделать это объект имеет все атрибуты, равные нулю.
Мой класс объекта:
public class User {
private String username;
private int shipCount;
private int structureCount;
private String joinedAt;
private int credits;
public User(String username, int shipCount, int structureCount, String joinedAt, int credits) {
this.username = username;
this.shipCount = shipCount;
this.structureCount = structureCount;
this.joinedAt = joinedAt;
this.credits = credits;
}
Плюс геттеры и сеттеры
Моя попытка использовать GSON:
Gson gso = new Gson();
User userInf = gso.fromJson(response.body(), User.class);
System.out.println(userInf);
Тело ответа такое:
{"user":{"username":":chrter","shipCount":0,"structureCount":0,"joinedAt":"2022-04-09T16:52:14.365Z","credits":0}}
Любая помощь приветствуется
но у меня есть геттеры и сеттеры, разве это не так?
Геттеры и сеттеры — это не то же самое, что общедоступное поле. Они также не делают поля общедоступными, так что нет, единственный способ — сделать эти поля общедоступными.
Все еще не работает с публичными полями, и я видел много случаев, когда поля были приватными, и это работало.
Тогда я не помню это правильно: D Это также может быть связано с тем, что ваш объект ответа имеет только одно поле - «пользователь», которое содержит остальную часть структуры. Затем GSON пытается присвоить поле JSON «пользователь» любому из полей класса «Пользователь». Это не то, что мы хотим, конечно. Попробуйте создать другой класс, в котором есть одно поле с именем user типа User, и вместо этого выполните десериализацию в этот класс, посмотрите, работает ли это.
Попробуйте что-то вроде этого:
public static Map<String, Object> Converter(String str){
Map<String, Object> map = new Gson().fromJson(str, new TypeToken<HashMap<String, Object>>() {}.getType());
return map;
}
Map<String, Object> apiResponse = Converter(response.body().toString());
Map<String, Object> username = Converter(apiResponse.get("user").toString());
System.out.println(username);
Немного подкорректируйте его в соответствии с вашими потребностями
Попробуй это.
Map<?, ?> map = gson.fromJson(response.body(), Map.class);
for (Map.Entry<?, ?> entry : map.entrySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
Корневой объект вашего HTTP-ответа — это объект JSON, который имеет только одно поле — "user"
. Когда GSON десериализует ответ, он проходит через все поля корневого объекта и устанавливает их в соответствующие поля предоставленного вами класса. Таким образом, он будет искать поле user
в классе User
и устанавливать его в данные JSON.
Поскольку в классе User
нет поля user
, GSON не заполняет это поле. На самом деле он не заполняет никаких других полей, потому что в корневом объекте нет других полей.
Чтобы обойти это, вам нужно десериализовать не весь ответ, а только поле user
корневого объекта. Есть два способа сделать это.
Десериализуйте корневой объект, а затем десериализуйте поле user
этого объекта в класс User
.
Вы можете найти пример того, как это сделать, в ответе @Saheed. Однако вы должны отметить, что он переводит строку JSON в объекты Java, а затем переводит объекты Java обратно. Это может стоить вам дополнительного времени, если вы делаете это в чувствительной к производительности области вашей программы.
Создайте еще один класс, в который вы будете десериализовать, у которого бы есть поле пользователя. Это выглядит так:
class Response {
public User user;
};
class User {
// ...
};
И затем вы десериализуете так:
Gson gso = new Gson();
// CHANGE: Deserialize the response and get the user field
Response response = gso.fromJson(response.body(),Response.class);
User userInf = response.user;
System.out.println(userInf);
Да, теперь это имеет гораздо больше смысла, я неправильно интерпретировал структуру json и то, как ее обрабатывает gson. Большое спасибо
Если я правильно помню, GSON будет устанавливать только общедоступные поля объекта, поэтому вам нужно сделать те поля, которые вы хотите установить, общедоступными.