Java/ Jackson - не сериализуйте класс обёртывания
При сериализации списка строк с помощью библиотеки Джексона он правильно предоставляет массив строк JSON:
<mapper>.writeValue(System.out, Arrays.asList("a", "b", "c"));
[ "a", "b", "c" ]
Однако строки заключены в класс в нашем коде:
public static class StringWrapper {
protected final String s;
public String getS() {
return s;
}
public StringWrapper(final String s) {
this.s = s;
}
}
При сериализации списка "переносчиков строк" я бы хотел получить тот же вывод, что и выше. Теперь я получаю:
<mapper>.writeValue(System.out, Arrays.asList(new StringWrapper("a"), new StringWrapper("b"), new StringWrapper("c")));
[ {
"s" : "a"
}, {
"s" : "b"
}, {
"s" : "c"
} ]
Какой самый удобный способ сделать это? Если возможно, десериализация также должна работать.
2 ответа
Ты можешь использовать @JsonValue
на вашем единственном добытчике
@JsonValue
public String getS() {
return s;
}
Из Javadoc,
Маркерная аннотация, похожая на javax.xml.bind.annotation.XmlValue, которая указывает, что результаты аннотированного метода "getter" (что означает, что сигнатура должна быть такой же, как у метода get; не возвращаемый тип void, без аргументов) должны использоваться в качестве единственного значение для сериализации для экземпляра. Обычно значение имеет простой скалярный тип (String или Number), но это может быть любой сериализуемый тип (Collection, Map или Bean).
Я вижу два возможных варианта. Если у вас есть StringWrapper
класс вы можете просто добавить @JsonValue
аннотация на геттере.
@JsonValue
public String getS() { return s; }
Если вам не разрешено изменять объект, также работает следующее потоковое решение:
mapper.writeValueAsString(listOfStringWrappers.stream().map(sw -> sw.getS()).toArray());