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
Adding Java Annotations at Runtime
Jpanel & Components Change Position Automatically
Use of Initializers VS Constructors in Java
Find Out If Class Name Contains Certain Text
How to Give Images Rounded Corners in Android
Android Firestore Convert Array of Document References to List<Pojo>
Convert Utc to Current Locale Time
Navigation Drawer Item Icon Not Showing Original Colour
How to Get Difference Between Two Dates in Android, Tried Every Thing and Post
Can Not Find the Tag Library Descriptor for "Http://Java.Sun.Com/Jsp/Jstl/Core"
Creating Runnable Jar with Gradle
Javafx - What Is This Weird Container That Holds Context Menu
How to Create Android Virtual Device
Code Will Only Return 0.0, 0.0 Gps Coordinate While Throwing Nullpointerexception
Passing a JavaScript Object Using Addjavascriptinterface() on Android