Jackson Enum Serializing and Deserializer

Jackson enum Serializing and DeSerializer

The serializer / deserializer solution pointed out by @xbakesx is an excellent one if you wish to completely decouple your enum class from its JSON representation.

Alternatively, if you prefer a self-contained solution, an implementation based on @JsonCreator and @JsonValue annotations would be more convenient.

So leveraging on the example by @Stanley the following is a complete self-contained solution (Java 6, Jackson 1.9):

public enum DeviceScheduleFormat {

Weekday,
EvenOdd,
Interval;

private static Map<String, DeviceScheduleFormat> namesMap = new HashMap<String, DeviceScheduleFormat>(3);

static {
namesMap.put("weekday", Weekday);
namesMap.put("even-odd", EvenOdd);
namesMap.put("interval", Interval);
}

@JsonCreator
public static DeviceScheduleFormat forValue(String value) {
return namesMap.get(StringUtils.lowerCase(value));
}

@JsonValue
public String toValue() {
for (Entry<String, DeviceScheduleFormat> entry : namesMap.entrySet()) {
if (entry.getValue() == this)
return entry.getKey();
}

return null; // or fail
}
}

Deserialise enum field with Jackson

Jackson deserialization method is called readValue.

The purpose of convertValue is different — it serializes an object (which may be a string — it would become a JSON-string-literal then) first, and then deserializes the result into an object of the target type.

The following should work:

Event deserialisedEvent = objectMapper.readValue(serialisedEvent, Event.class);

Jackson: Serialize and deserialize enum values as integers

It should work by specifying JsonValue mapper.

public enum State {
OFF,
ON,
UNKNOWN;

@JsonValue
public int toValue() {
return ordinal();
}
}

This works for deserialization also, as noted in Javadoc of @JsonValue annotation:

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

Jackson Serializaiton/Deserialization by custom property in enum

Managed to get it working:

@JsonSerialize(using = StringIdEnumSerializer::class)
@JsonDeserialize(using = StringIdEnumDeserializer::class)
interface StringIdEnum: DbEnum {

val stringId: String

}
class StringIdEnumSerializer: StdSerializer<StringIdEnum>(StringIdEnum::class.java) {

override fun serialize(value: StringIdEnum, gen: JsonGenerator, provider: SerializerProvider) {
gen.writeString(value.stringId)
}

}
class StringIdEnumDeserializer : JsonDeserializer<Enum<*>>(), ContextualDeserializer {

private lateinit var type: JavaType

override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Enum<*> {
val t = p.text
val enumConstants = (type.rawClass as Class<Enum<*>>).enumConstants
return enumConstants.single { (it as StringIdEnum).stringId == t }
}

override fun createContextual(ctxt: DeserializationContext?, property: BeanProperty?): JsonDeserializer<*> {
val wrapperType: JavaType = property!!.type
val stringIdEnumDeserializer = StringIdEnumDeserializer()
stringIdEnumDeserializer.type = wrapperType
return stringIdEnumDeserializer
}
}

Jackson - Serialize / Deserialize Enums with Integer fields

This can be achieved using Jackson annotation @JsonCreator. For serialization, a method with @JsonValue can return an int and for deserialization, a static method with @JsonCreator can accept an int in parameter as provided below.

Code below for reference:

enum State{
GOOD(1), BAD(-1), UGLY(0);

int id;

State(int id) {
this.id = id;
}

@JsonValue
int getId() {
return id;
}

@JsonCreator
static State fromId(int id){
return Stream.of(State.values()).filter(state -> state.id == id).findFirst().get();
}

}

Note: This is currently an open bug on Jackson library - https://github.com/FasterXML/jackson-databind/issues/1850



Related Topics



Leave a reply



Submit