cubesoft cubesoft -4 years ago 58
Android Question

java jackson json processor - using in RestTemplate - handling of EnumSet

I have an Android app that connects to a JSON WebService. One of the methods returns comma separated string list for "flag-type" value, in other words a bit mask. For instance, it returns "FileAppend, FileOverwrite". For this type I have a java enum defined

enum FileMode { FileAppend, FileOverwrite, ... }


and want Jackson deserializer to automatically convert the returned String list in JSON payload into the enum. I tried both raw Enum FileMode and EnumSet but I get exceptions in both cases while deserialization. Is there a way to annotate somehow so that the deserializer know how to deserialize it?

@JsonIgnoreProperties(ignoreUnknown=true)
@JsonTypeName("AccessMask")
@JsonAutoDetect
public enum AccessMask {
None,

HideDateCreated,
HideDateModified,
HideDateTaken,
HideMetaData,
HideUserStats,
HideVisits,

NoCollections,
NoPrivateSearch,
NoPublicSearch,
NoRecentList,

ProtectExif,
ProtectXXLarge, // new in version 1.3
ProtectExtraLarge,
ProtectLarge,
ProtectMedium,
ProtectOriginals,

ProtectGuestbook, // new in version 1.1
NoPublicGuestbookPosts, // new in version 1.1
NoPrivateGuestbookPosts, // new in version 1.1
NoAnonymousGuestbookPosts, // new in version 1.1

ProtectComments, // new in version 1.1
NoPublicComments, // new in version 1.1
NoPrivateComments, // new in version 1.1
NoAnonymousComments, // new in version 1.1

PasswordProtectOriginals, // new in version 1.2

ProtectAll }

// and below is a property of a class defined below.
class Picture {
@JsonProperty("AccessMask")
EnumSet<AccessMask> accessMask;
}


AccessMask is a bit field meaning it can have multiple field set (bit mask).
When I deserialize this class using JSON deserializer, I got the following exception
nested exception is org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.EnumSet out of VALUE_STRING token

What may be the reason?

Regards

Answer Source

If value is -- as error message suggests -- just a JSON String, and not as would expected, an array of Strings, you need to write a custom deserializer. But why are these not serialized as JSON arrays with enum values as individual Strings? Jackson would handle this automatically without any annotations (none of annotations you added are needed, I assume they were added to try to make things work?).

You can register deserializer either directly on field (@JsonDeserialize(using=MyDeserializer.class)) or by registering deserializer for that type.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download