Я использую Джексона в java для десериализации json blob, который состоит из карты объектов. Но, к сожалению, мой код выдает исключение.
У меня есть следующий удар данных, который я хочу десериализовать с помощью Джексона:
"config": {
"configItem1": {
"0": {
"valueBit": false,
"valueInt": 0,
"valueFloat": 0,
"timestamp": "2016-10-05T13:44:04.223Z"
},
"1": {
"valueBit": false,
"valueInt": 0,
"valueFloat": 0,
"timestamp": "2016-10-05T13:44:04.223Z"
}
},
"configItem2": {
"0": {
"valueBit": false,
"valueInt": 0,
"valueFloat": 0,
"timestamp": "2018-03-15T11:39:47.550Z"
}
}
}
И у меня есть следующий класс модели, в который я пытаюсь сериализовать:
public class VehicleConfigValues {
private final Boolean valueBit;
private final Integer valueInt;
private final Double valueFloat;
private final DateTime valueDate;
private final DateTime timestamp;
private final String changedBy;
public ConfigValues(Boolean valueBit, Integer valueInt, Double valueFloat, DateTime valueDate, DateTime timestamp, String changedBy) {
this.valueBit = valueBit;
this.valueInt = valueInt;
this.valueFloat = valueFloat;
this.valueDate = valueDate;
this.timestamp = timestamp;
this.changedBy = changedBy;
}
final static ConfigValues defaultConfig = new ConfigValues(false, 0, 0.0, null, null, null);
public Boolean getValueBit() {
return valueBit;
}
public Integer getValueInt() {
return valueInt;
}
public Double getValueFloat() {
return valueFloat;
}
public DateTime getValueDate() {
return valueDate;
}
public DateTime getTimestamp() {
return timestamp;
}
public String getChangedBy() {
return changedBy;
}
}
public class Config {
private Map<String, Map<Integer, ConfigValues>> config;
public Config() {
}
public Config(Map<String, Map<Integer, ConfigValues>> config) {
this.config = config;
}
public Map<String, Map<Integer, ConfigValues>> getConfig() {
return config;
}
}
И у меня есть следующий основной метод, вызывающий десериализацию указанного выше блоба в эти классы:
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
try {
// Convert JSON string from file to Object
Config user = mapper.readValue(new File("C:\\mConfig\\config.json"), Config.class);
System.out.println(user);
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Но, к сожалению, я получаю следующую ошибку:
org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class ConfigValues]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: C:\Config\config.json; line: 5, column: 17] (through reference chain: Config["config"])
Кто-нибудь может пролить свет на это? Мне сложно отладить, почему эта десериализация не работает
Вы можете попробовать это:
Map<String, Config> map = mapper.readValue(jsonInput, new TypeReference<HashMap<String, Config>>() {});
Привет, спасибо за помощь. Но даже с этим кодом я все равно получаю сообщение об ошибке: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: нераспознанное поле «configItem1» (конфигурация класса), не отмеченное как игнорируемое в [Источник:; строка: 3, столбец: 28] (через цепочку ссылок: Config ["configItem1"])
Измените определение бобов, как указано ниже
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.ext.JodaSerializers.DateTimeSerializer;
import org.joda.time.DateTime;
public class ConfigValues {
private final Boolean valueBit;
private final Integer valueInt;
private final Double valueFloat;
private final DateTime valueDate;
private final DateTime timestamp;
private final String changedBy;
@JsonCreator
public ConfigValues(
@JsonProperty("valueBit") Boolean valueBit,
@JsonProperty("valueInt") Integer valueInt,
@JsonProperty("valueFloat") Double valueFloat,
@JsonSerialize(using = DateTimeSerializer.class) @JsonProperty("valueDate") DateTime valueDate,
@JsonSerialize(using = DateTimeSerializer.class) @JsonProperty("timestamp") DateTime timestamp,
@JsonProperty("changedBy") String changedBy) {
this.valueBit = valueBit;
this.valueInt = valueInt;
this.valueFloat = valueFloat;
this.valueDate = valueDate;
this.timestamp = timestamp;
this.changedBy = changedBy;
}
final static ConfigValues defaultConfig = new ConfigValues(false, 0, 0.0, null, null, null);
public Boolean getValueBit() {
return valueBit;
}
public Integer getValueInt() {
return valueInt;
}
public Double getValueFloat() {
return valueFloat;
}
public DateTime getValueDate() {
return valueDate;
}
public DateTime getTimestamp() {
return timestamp;
}
public String getChangedBy() {
return changedBy;
}
}
а также
import java.util.Map;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
public class Config {
private final Map<String, Map<Integer, ConfigValues>> config;
@JsonCreator
public Config(@JsonProperty("config") Map<String, Map<Integer, ConfigValues>> config) {
this.config = config;
}
public Map<String, Map<Integer, ConfigValues>> getConfig() {
return config;
}
}
Несколько очков:
@JsonCreator
необходим, если вы хотите сериализовать финальный класс. Его следует использовать в конструкторе, и в этом случае аннотация @JsonProperty является обязательной для параметров.Спасибо за вашу помощь! К сожалению, даже с этими изменениями я все еще получаю «ошибку нераспознанного поля» в «configitem1». Разве это не идентифицирует эти поля как элементы на карте?
Выше рабочий код, который я написал в eclipse и запустил с помощью codehaus lib версии 1.8.5. Какую версию библиотеки Джексона вы используете
Привет, я использую библиотеку jackson-all-1.9.0. Стоит ли мне переехать в Джексон 2?
Я использую эту библиотеку mvnrepository.com/artifact/org.codehaus.jackson/…. Код работает нормально даже с этой версией jar.
Когда я запускаю IntelliJ, все еще выдает ошибку, внесли ли вы какие-либо изменения в большой двоичный объект JSON или основной метод приложения?
Просто добавил ваш json в фигурные скобки, так как он недействителен. Также отредактировал рассматриваемый json. Основной метод такой же.
Позвольте нам продолжить обсуждение в чате.
Сама ошибка возникает из-за того, что класс не определяет конструктор без аргументов ("по умолчанию") ИЛИ конструктор / статический фабричный метод, аннотированный
@JsonCreator
. В принятом ответе показано, как это сделать, но вы можете в качестве альтернативы добавить конструктор без аргументовprivate
для использования Джексоном: это также будет работать, а затем для присвоения значений будут использоваться методы набора (или поля напрямую).