#java #xml #jackson #deserialization #newline
#java #xml #джексон #десериализация #новая строка
Вопрос:
Есть следующие 2 класса:
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Structure {
@JacksonXmlProperty
private Info info;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@NoArgsConstructor
@AllArgsConstructor
public class Info{
private Subinfo subinfo;
}
выполнение десериализации, как:
private static final XmlMapper XML_MAPPER = new XmlMapper();
Structure structure = XML_MAPPER.readValue(input, Structure.class);
где input
мой XML (см. Ниже)
получено исключение:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.test.models.Info` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('
')
эта функция Джексона не помогла:
XML_MAPPER.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
мой XML, который не удался:
<?xml version='1.0' encoding='UTF-8' ?>
<Structure>
<Info>
</Info>
</Structure>
для этого десериализация XML работает нормально:
<?xml version='1.0' encoding='UTF-8' ?>
<Structure>
<Info/>
</Structure>
Проблема заключается в подходе к закрытию тега:
<Info/>
против <Info></Info>
<Info/>
работает нормально, пока
<Info>
</Info>
вызывает исключение при возникновении прерывателей строки
Комментарии:
1.
<Info/>
является пустой строкой.<Info></Info>
является пустой строкой.<Info> </Info>
это не пустая строка, поскольку она состоит из пробельных символов. В вашем примере он, похоже, состоит из символа завершения строки (n
илиrn
, в зависимости от ОС) и 4 пробелов.2. @Andreas вы правы, это мой вклад, проблема в том, что функция
DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT
здесь не работает3. Извините, Jackson обрабатывает только пустые строки, а не пустые строки. Если вам это нужно, вы должны написать некоторую логику десериализации самостоятельно.
4. Не могли бы вы предоставить минимальный git? Мой код работает просто отлично
5. Оба работают нормально @sergionni imgur.com/JicmNj0
Ответ №1:
Как уже упоминали другие в своих комментариях, DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT
преобразует только пустые строки в null, но у вас есть пробелы и разделители строк в вашем информационном элементе.
Другие не могут воспроизвести вашу проблему, поскольку вы либо не упомянули, что вы также используете XML_MAPPER.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
в своем коде, либо Info в вашем примере XML на самом деле должен быть info, иначе элемент игнорируется.
Для обработки пустых строк и строк, содержащих только пробелы и / или разделители строк, вы можете добавить следующий код перед анализом XML:
XML_MAPPER.addHandler(new DeserializationProblemHandler() {
@Override
public Object handleMissingInstantiator(DeserializationContext ctxt, Class<?> instClass,
ValueInstantiator valueInsta, JsonParser p, String msg) throws IOException {
String value = p.getValueAsString();
// ignore "empty" Info elements
if (instClass.isAssignableFrom(Info.class) amp;amp; (value.isEmpty() || value.matches("[ns] "))) {
return null;
}
return super.handleMissingInstantiator(ctxt, instClass, valueInsta, p, msg);
}
});
Если вы хотите сделать это для всех элементов, вы можете просто игнорировать instClass