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());
Другие вопросы по тегам