Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GSON. workaround for enum and int

Tags:

json

gson

I get a json-answer from server. And i'm parsing it with GSON-library.

A key within json has an integer value. Is it somehow possible without to change the server answer (it is the external server interface, we have no influence on it) to cast the integer value to an enumeration?

Thank you.

UPD:

The json-Response. NOTE: we can't change it

"testObject":{
"id":123,
"type":42
}

The enumeration:

public enum ObjectTypeEnum
{
    UNKNOWN_TYPE(0),
    SIMPLE_TYPE(11),
    COMPLEX_TYPE(42);

    private int value;

    private ObjectTypeEnum(int value)
    {
        this.value = value;         
    }

    public static ObjectTypeEnum findByAbbr(int value)
    {
        for (ObjectTypeEnum currEnum : ObjectTypeEnum.values())
        {
            if (currEnum.value == value)
            {
                return currEnum;
            }
        }

        return null;
    }

    public int getValue()
    {
        return value;
    }
}

And the object class

public class TestObject
{
    publuc int id;
    public ObjectTypeEnum type; 
}
like image 411
Tima Avatar asked Sep 12 '11 08:09

Tima


People also ask

Does Gson ignore transient fields?

Gson serializer will ignore every field declared as transient: String jsonString = new Gson().

How does Gson serialize enum?

By default, Gson serializes enums by name in lowercase. If this is not sufficient and you want some other string or an integer value, then have a look at the @SerializedName annotation. Gson can serialize and deserialize enums using the @SerializedName annotation.

Does Gson ignore extra fields?

3. Deserialize JSON With Extra Unknown Fields to Object. As you can see, Gson will ignore the unknown fields and simply match the fields that it's able to.

What does Gson toJson do?

Introduction. Gson is the main actor class of Google Gson library. It provides functionalities to convert Java objects to matching JSON constructs and vice versa. Gson is first constructed using GsonBuilder and then toJson(Object) or fromJson(String, Class) methods are used to read/write JSON constructs.


2 Answers

You can just use the @SerializedName annotation to determine what value gets serialized to/from the wire. Then you don't need to write a custom TypeAdapter.

import com.google.gson.annotations.SerializedName;

public enum ObjectTypeEnum {
    @SerializedName("0")
    UNKNOWN_TYPE(0),

    @SerializedName("11")
    SIMPLE_TYPE(11),

    @SerialziedName("42")
    COMPLEX_TYPE(42);

    private int value;

    private ObjectTypeEnum(int value) {
        this.value = value;         
    }

    public int getValue() {
        return value;
    }
}

If you don't have a need for getting the wire value in your code you can eliminate the "value" field and related code.

public enum ObjectTypeEnum {
    @SerializedName("0")
    UNKNOWN_TYPE,

    @SerializedName("11")
    SIMPLE_TYPE,

    @SerialziedName("42")
    COMPLEX_TYPE;
}
like image 55
kjones Avatar answered Sep 22 '22 08:09

kjones


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

like image 30
Tima Avatar answered Sep 19 '22 08:09

Tima