#java #json #jackson
#java #json #джексон
Вопрос:
У меня есть этот фрагмент кода, который сериализует подкласс Map с использованием Jackson. Без зарегистрированного сериализатора я получаю действительный json, я использую сериализатор, чтобы перевести имя в нижний регистр. Однако созданный json выглядит так:
{:"two":"aaa":"one":"aaa"}
Есть идеи, почему? Как исправить?
@Test
public void test_serialization() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("JSONModule", new Version(1, 0, 0, null, null, null));
module.addSerializer(Circle.class, new CircleSerializer());
module.addKeySerializer(Circle.class, new CircleSerializer());
mapper.registerModule(module);
CircleMap statistics = new CircleMap();
statistics.put(Circle.ONE, "aaa");
statistics.put(Circle.TWO, "aaa");
System.out.println(mapper.writeValueAsString(statistics));
}
enum Circle {
ONE, TWO
}
static class CircleMap extends HashMap<Circle, String> {
}
static class CircleSerializer extends JsonSerializer<Circle> {
@Override
public void serialize(Circle value, JsonGenerator gen, SerializerProvider provider) throws IOException, JsonProcessingException {
gen.writeString(value.name().toLowerCase());
}
}
Комментарии:
1. Прокомментируйте свою
module.addKeySerializer
реплику, и она должна сработать.2. Я не думаю, что это заслуживает понижения. Это был полностью рабочий пример, демонстрирующий проблему.
Ответ №1:
Заменить
gen.writeString(value.name().toLowerCase());
с
gen.writeFieldName(value.name().toLowerCase());
Вы сериализуете ключ. Это интерпретируется как имя поля JSON, поэтому вы должны использовать этот метод. writeString
государства javadoc
Способ вывода строкового значения. В зависимости от контекста это означает либо элемент массива, либо значение поля (объекта), либо отдельную строку;
Вы прямо пишете строковое значение. Это не то, что вы хотите.
Обратите внимание, что вам понадобится другой сериализатор для ключей и для обычных значений.