#java #json #serialization #jackson #deserialization
#java #json #сериализация #джексон #десериализация
Вопрос:
Итак, я работаю над десериализацией вложенного JSONObject, но не хочу создавать класс для каждого вложенного объекта. Я пытался использовать один из вложенных JSONObjects и поместить его в JSONObject.
public class ContainerStatus {
@JsonProperty("name")
private String name;
@JsonProperty("state")
private JSONObject state;
@JsonProperty("lastState")
private JSONObject lastState;
@JsonProperty("ready")
private Boolean ready;
@JsonProperty("restartCount")
private Integer restartCount;
@JsonProperty("image")
private String image;
@JsonProperty("imageID")
private String imageID;
@JsonProperty("containerID")
private String containerID;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
Используя это для десериализации:
{ "containerStatuses":
{
"name": "connect",
"state": {
"terminated": {
"exitCode": 1,
"reason": "Error",
"startedAt": "2019-03-20T15:40:08Z",
"finishedAt": "2019-03-20T15:40:50Z",
"containerID": "docker://"
}
},
"lastState": {},
"ready": true,
"restartCount": 0,
"image": "image",
"imageID": "docker-pullable://",
"containerID": "docker://"
}}
Я получаю нераспознанное поле «terminated» из-за состояния JSONObject.
Я хочу:
JsonObject state = {
"terminated": {
"exitCode": 1,
"reason": "Error",
"startedAt": "2019-03-20T15:40:08Z",
"finishedAt": "2019-03-20T15:40:50Z",
"containerID": "docker://"
}
}
Я могу преобразовать его в универсальный объект, но формат больше не JSON:
@JsonProperty("state")
private Object state;
Gives me this format:
{running={startedAt=2019-03-20T14:53:53Z}}
Ответ №1:
Вам нужно немного улучшить свой пример:
DeserializationFeature.UNWRAP_ROOT_VALUE
, включите эту функцию для разворачиванияJSON
объекта.- Добавьте
JsonRootName
аннотацию к вашемуPOJO
классу, потому что имя класса не совпадает со свойствомcontainerStatuses
. - Используйте
JsonNode
то, что поступает изJackson
библиотеки, вместоJSONObject
того, что, вероятно, поступает изorg.json
.
Улучшенный пример может выглядеть следующим образом:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonApp {
public static void main(String[] args) throws Exception {
String json = "{...}";
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
ContainerStatus cs = mapper.readValue(json, ContainerStatus.class);
System.out.println(cs.getState());
}
}
@JsonRootName("containerStatuses")
class ContainerStatus {
@JsonProperty("name")
private String name;
@JsonProperty("state")
private JsonNode state;
@JsonProperty("lastState")
private JsonNode lastState;
@JsonProperty("ready")
private Boolean ready;
@JsonProperty("restartCount")
private Integer restartCount;
@JsonProperty("image")
private String image;
@JsonProperty("imageID")
private String imageID;
@JsonProperty("containerID")
private String containerID;
// getters, setters, toString
}
Приведенный выше код выводит:
{"terminated":{"exitCode":1,"reason":"Error","startedAt":"2019-03-20T15:40:08Z","finishedAt":"2019-03-20T15:40:50Z","containerID":"docker://"}}
Комментарии:
1. Изменение его на JsonNode решило проблему, и теперь я получаю его как JSON. Спасибо!