Как аннотировать поля enum для десериализации с использованием Jackson json
Джексон 1.6.2
Веб-сервис REST/Apache Wink
Как аннотировать поле перечисления, чтобы Джексон десериализовал его?
Внутренний класс
public enum BooleanField
{
BOOLEAN_TRUE { public String value() { return "1";} },
BOOLEAN_FALSE { public String value() { return "0";} },
Java Bean/Объект запроса
BooleanField locked;
public BooleanField getLocked() {return locked;}
В документах Jackson указано, что он может сделать это через @JsonValue
/@JsonCreator
, но не дает примеров (насколько полезно!). Я уверен, что они просто не хотят, чтобы слишком много людей использовали свои рамки, чтобы сохранить эту тайну.
Любой, кто хочет разлить (java) beans, как бы?
Ответы
Ответ 1
Если вы используете Jackson 1.9, сериализация будет выполняться с помощью:
public enum BooleanField {
BOOLEAN_TRUE("1")
;
// either add @JsonValue here (if you don't need getter)
private final String value;
private BooleanField(String value) { this.value = value; }
// or here
@JsonValue public String value() { return value; }
поэтому вам нужно добавить метод к типу Enum, так что все значения имеют его. Не уверен, будет ли он работать с подтипом.
Для @JsonCreator
, используя статический метод factory; поэтому добавление чего-то вроде:
@JsonCreator
public static BooleanField forValue(String v) { ... }
Jackson 2.0 фактически поддерживает использование только @JsonValue
для обоих, включая десериализацию.
Ответ 2
С Jackson 2.7.2 или новее
public enum BooleanField
{
@JsonProperty("1")
BOOLEAN_TRUE,
@JsonProperty("0")
BOOLEAN_FALSE
}
Ответ 3
не комментируйте их, просто настройте экземпляр ObjectMapper:
private ObjectMapper createObjectMapper() {
final ObjectMapper mapper = new ObjectMapper();
// enable toString method of enums to return the value to be mapped
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
return mapper;
}
и в вашем перечислении переопределите метод toString():
public enum SectionType {
START("start"),
MORE("more");
// the value which is used for matching
// the json node value with this enum
private final String value;
SectionType(final String type) {
value = type;
}
@Override
public String toString() {
return value;
}
}
Вам не нужны аннотации или пользовательские десериализаторы.
Ответ 4
Собственно, согласно документам для JsonValue (Jackson 2.3.3):
NOTE: when use for Java enums, one additional feature is
* that value returned by annotated method is also considered to be the
* value to deserialize from, not just JSON String to serialize as.
* This is possible since set of Enum values is constant and it is possible
* to define mapping, but can not be done in general for POJO types; as such,
* this is not used for POJO deserialization.
Итак, для перечислений ваша десериализация не будет работать с использованием JsonCreator, потому что JsonValue будет использоваться как для сериализации, так и для десериализации.
Один из способов сделать это для перечислений - использовать JsonSetter и JsonGetter.
Ответ 5
Если перечисление является массивом или нет, может работать следующее. (Только для десериализации)
package com.stack.model;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder({ "success", "my-enums" })
public class MyObjectJSON {
@JsonProperty("sucess")
private boolean success;
@JsonProperty("my-enums")
private MyEnum[] myEnums;
static enum MyEnum {
Enum1, Enum2, Enum3, Enum4, EnumN;
private static Map<String, MyEnum> myEnumsMap = new HashMap<String, MyEnum>(5);
static {
myEnumsMap.put("enum1-val", Enum1);
myEnumsMap.put("enum2-val", Enum2);
myEnumsMap.put("enum3-val", Enum3);
myEnumsMap.put("enum4-val", Enum4);
myEnumsMap.put("enumn-val", EnumN);
}
@JsonCreator
public static MyEnum forValue(String value) {
return myEnumsMap.get(value.toLowerCase());
}
}
}
Считать:
- Аннотации @Data генерируют сеттеры, getters, toString и т.д.
-
@JsonProperty ( "my-enums" ) private MyEnum [] myEnums, это способ аннотировать с джексоном поле, которое имеет тип Enum (
Он работает, если это массив или нет).
-
MyEnum - это перечисление значений, которые должны отображаться для объекта JSON, предположим, что следующий объект:
{ "sucess": true, "my-enums": [ "enum1-val", "enum3-val" ]
}
-
Функция forValue позволяет сопоставлять строковые значения массива Enum, он аннотируется с помощью @JsonCreator, чтобы указать конструкцию factory, используемую при десериализации.