Using Enums while parsing JSON with GSON
From the documentation for Gson:
Gson provides default serialization and deserialization for Enums... If you would prefer to change the default representation, you can do so by registering a type adapter through GsonBuilder.registerTypeAdapter(Type, Object).
Following is one such approach.
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
public class GsonFoo
{
public static void main(String[] args) throws Exception
{
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(AttributeScope.class, new AttributeScopeDeserializer());
Gson gson = gsonBuilder.create();
TruncateElement element = gson.fromJson(new FileReader("input.json"), TruncateElement.class);
System.out.println(element.lower);
System.out.println(element.upper);
System.out.println(element.delimiter);
System.out.println(element.scope.get(0));
}
}
class AttributeScopeDeserializer implements JsonDeserializer<AttributeScope>
{
@Override
public AttributeScope deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
AttributeScope[] scopes = AttributeScope.values();
for (AttributeScope scope : scopes)
{
if (scope.scope.equals(json.getAsString()))
return scope;
}
return null;
}
}
class TruncateElement
{
int lower;
int upper;
String delimiter;
List<AttributeScope> scope;
}
enum AttributeScope
{
TITLE("${title}"), DESCRIPTION("${description}");
String scope;
AttributeScope(String scope)
{
this.scope = scope;
}
}
Setting default Enum while parsing using Gson
I have two options.
Make
Status
beString
Use
Gson
custom deserializer like this(Kotlin example).class StatusDeserializer : JsonDeserializer<Status> {
override fun deserialize(
json: JsonElement,
typeOfT: Type,
context: JsonDeserializationContext
): Status {
val jsonObject = json.asJsonObject
return when(jsonObject.get("status").asString) {
"A", "B", "C", "D" -> context.deserialize<Status>(jsonObject, Status::class.java)
else -> Status.DEFAULT
}
}
}
val gson = GsonBuilder().registerTypeAdapter(Status::class.java, StatusDeserializer()).create()
serialize and deserialize enum with Gson
According to Gson API documentation, Gson provides default serialization/deserialization of Enum
, so basically it should be serialized and deserialized using the standard toJson
and fromJson
methods, as with any other type.
Serializing a map of enums with Gson with custom serialization
Gson uses a dedicated serializer for Map
keys. This, by default, use the toString()
of the object that's about to be used as a key. For enum
types, that's basically the name of the enum
constant. @SerializedName
, by default for enum
types, will only be used when serialized the enum
as a JSON value (other than a pair name).
Use GsonBuilder#enableComplexMapKeySerialization
to build your Gson
instance.
private static Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
GSON. workaround for enum and int
Using an answer from Chin and help from my workmate I get following solution.
I wrote an inner class in the parser class.
private static class ObjectTypeDeserializer implements
JsonDeserializer<ObjectTypeEnum>
{
@Override
public PreconditioningStatusEnum deserialize(JsonElement json,
Type typeOfT, JsonDeserializationContext ctx)
throws JsonParseException
{
int typeInt = json.getAsInt();
return ObjectTypeEnum
.findByAbbr(typeInt);
}
}
and created GSON-Object on following way:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(ObjectTypeEnum.class, new ObjectTypeDeserializer() );
Gson gson = gsonBuilder.create();
http://sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserializ
How to parse JSON objects into an enum
You can create a deserializer for TspEnum
:
class TspDeserializer : JsonDeserializer<TspEnum> {
override fun deserialize(json: JsonElement, typeOfT: Type?, context: JsonDeserializationContext?): TspEnum {
val stringValue = json.asString
for (enum in TspEnum.values()) {
if (enum.provider == stringValue) {
return enum
}
}
throw IllegalArgumentException("Unknown tsp $stringValue!")
}
}
next you have to register it:
val gson = GsonBuilder()
.registerTypeAdapter(TspEnum::class.java, TspDeserializer())
.create()
and then you can parse your user:
val user = gson.fromJson(json, User::class.java)
println(user) // prints User(tsp=AY_BEE_CEE, userId=lkajsdlk-199191-lkjdflakj)
Related Topics
Spring Autowiring Class VS. Interface
Java/Convert Iso-8601 (2010-12-16T13:33:50.513852Z) to Date Object
Run Command Prompt as Administrator
Variable Naming Conventions in Java
Using Java Map for Range Searches
Class.Getresource() Returns Null
What Does Biginteger Having No Limit Mean
Getting Class Type from String
Compare One String with Multiple Values in One Expression
What Is the Priority of Casting in Java
Is There a Difference in Removing the Curly Braces from If Statements in Java
How to Check If a String Contains Only Digits in Java
Servlet Seems to Handle Multiple Concurrent Browser Requests Synchronously
Java's Date(...) Constructor Is Deprecated; What Does That Mean