Я использую JAVA 1.6 и Jackson 1.9.9 У меня есть enum
public enum Event {
FORGOT_PASSWORD("forgot password");
private final String value;
private Event(final String description) {
this.value = description;
}
@JsonValue
final String value() {
return this.value;
}
}
Я добавил @JsonValue, похоже, он выполняет работу по сериализации объекта в:
{"event":"forgot password"}
но когда я пытаюсь десериализовать, я получаю
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.globalrelay.gas.appsjson.authportal.Event from String value 'forgot password': value not one of declared Enum instance names
Что мне здесь не хватает?
java
enums
jackson
jsonserializer
pookieman
источник
источник
{"Event":"FORGOT_PASSWORD"}
? Обратите внимание на заглавные буквы на Event и FORGOT_PASSWORD.getValue
этогоGetValue
не работаетОтветы:
Решение для сериализатора / десериализатора, на которое указывает @xbakesx, является отличным решением, если вы хотите полностью отделить свой класс enum от его представления JSON.
В качестве альтернативы, если вы предпочитаете автономное решение, реализация на основе
@JsonCreator
и@JsonValue
аннотации будет более удобной.Таким образом, используя пример @Stanley, ниже приведено полное автономное решение (Java 6, Jackson 1.9):
источник
Обратите внимание, что с этого коммита в июне 2015 года (Jackson 2.6.2 и выше) вы теперь можете просто написать:
источник
Вы должны создать статический метод фабрики, который принимает один аргумент и комментирует его
@JsonCreator
(доступно с версии Jackson 1.2)Подробнее об аннотации JsonCreator читайте здесь .
источник
@JSONValue
сериализовать и@JSONCreator
десериализовать.@JsonCreator public static Event valueOf(int intValue) { ... }
десериализоватьint
вEvent
счетчик.Фактический ответ:
Десериализатор по умолчанию для перечислений использует
.name()
для десериализации, поэтому он не использует@JsonValue
. Таким образом, как указал @OldCurmudgeon, вам нужно пройти,{"event": "FORGOT_PASSWORD"}
чтобы соответствовать.name()
значению.Другой вариант (если вы хотите, чтобы значения json для записи и чтения были одинаковыми) ...
Больше информации:
Существует (еще) другой способ управления процессом сериализации и десериализации с Джексоном. Вы можете указать эти аннотации, чтобы использовать свой собственный сериализатор и десериализатор:
Затем вы должны написать,
MySerializer
иMyDeserializer
которые выглядят так:MySerializer
MyDeserializer
Последнее, особенно для выполнения перечисления
JsonEnum
, сериализованного с методомgetYourValue()
, ваш сериализатор и десериализатор может выглядеть так:источник
Я нашел очень хорошее и краткое решение, особенно полезное, когда вы не можете изменить перечисляемые классы, как это было в моем случае. Затем вы должны предоставить пользовательский ObjectMapper с включенной определенной функцией. Эти функции доступны с версии Jackson 1.6. Так что вам нужно только написать
toString()
метод в вашем перечислении.Доступны дополнительные функции, связанные с enum, см. Здесь:
https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features
источник
Попробуй это.
источник
Вы можете настроить десериализацию для любого атрибута.
Объявите свой класс десериализации, используя annotationJsonDeserialize (
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
) для атрибута, который будет обработан. Если это Enum:Таким образом, ваш класс будет использоваться для десериализации атрибута. Это полный пример:
источник
Существуют различные подходы, которые можно использовать для выполнения десериализации объекта JSON в enum. Мой любимый стиль - сделать внутренний класс:
источник
Вот еще один пример, который использует строковые значения вместо карты.
источник
В контексте перечисления использование
@JsonValue
now (начиная с 2.0) работает для сериализации и десериализации.Согласно Джексон-аннотации Javadoc для
@JsonValue
:Таким образом,
Event
аннотированное перечисление, как указано выше, работает (как для сериализации, так и для десериализации) с Jackson 2.0+.источник
Помимо использования @JsonSerialize @JsonDeserialize, вы также можете использовать SerializationFeature и DeserializationFeature (привязка Джексона) в сопоставителе объектов.
Например, DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, которые дают тип перечисления по умолчанию, если предоставленный тип не определен в классе перечисления.
источник
Самый простой способ, который я нашел, - это использование аннотации @ JsonFormat.Shape.OBJECT для перечисления.
источник
В моем случае это то, что решено:
Сериализует и десериализует следующий json:
Я надеюсь, что это помогает!
источник