0

I'm using a library with a class to map a json message and I'm using Gson to serialized the classes over json. The message contains a data field. The field is generic and it contains anything. The class provided by the library is:

public class Api {
....
@SerializedName("data")
Map<String, JsonElement> data;
....
}

Now I'd like to extend the class but I have my own root object to map the data sub field, so to do a summary the json is something like:

{...., "data": {"myownroot":"aaaa"}}

How can I do? I could create my own classes of course but I would prefer to extend the library if possible. If I extend the class I would have:

public class MyOwnRoot extends Api {
@SerializedName("myownroot")
public String root;
}

but in this case when I serialize it doesn't work because myownroot must be a child of data but how can I say to Gson "put MyOwnRoot in the data map"??

5
  • class Blah extends Api ? Commented Jun 7, 2017 at 17:03
  • It was obvious but I can't redefine the data field if I extend the class in this way
    – greywolf82
    Commented Jun 7, 2017 at 17:04
  • It's not really clear why you need to. The field is inherited Commented Jun 7, 2017 at 17:05
  • See edit please
    – greywolf82
    Commented Jun 7, 2017 at 17:07
  • I think you would have to write a custom serializer in order to handle what you're asking. github.com/google/gson/blob/master/… Commented Jun 7, 2017 at 17:22

1 Answer 1

1

I can't really understand why you would need to extend the Api class. I guess the class name is a bit of a misnomer, since API are (generally speaking) interfaces, and they get implemented.

I guess you could do this by using getters to your advantages, while letting Gson do its work on fields.

EDIT: To serialize also

public class Api {
    @SerializedName("data")
    protected Map<String, JsonElement> data;
}

public class RootEntity extends Api {
    transient StructuredRootImpl _cached;
    transient Gson _gson = new Gson();

    public class StructuredRootImpl {
        Integer v;
        String name;
    }

    public Integer getV() {
        synch();
        return _cached.v;
    }

    public void setV(Integer v) {
        _cached.v=v;
        synch();
    }

    private void synch() {
        if(_cached==null){
            if(data==null){
                data = new LinkedHashMap<>();
            }
            JsonElement jsonElement = data.get("myroot");
            _cached = _gson.fromJson(jsonElement, StructuredRootImpl.class);
        }
        JsonElement jsonTree = _gson.toJsonTree(_cached);
        data.put("myroot", jsonTree);
    }

    public String getName() {
        synch();
        return _cached.name;
    }

    public void setName(String name) {
        _cached.name = name;
        synch();
    }

    @Override
    public String toString() {
        return "RootEntity [v=" + getV() + ", n=" + getName() + "]";
    }

}

Running the main you can both serialize and deserialize your entity.

public class TestGson {

    public static void main(String[] args) {
        String jsonText = "{data:{\"myroot\":{\"v\":123,\"name\":\"mario\"}}}";
        Gson gson = new Gson();
        RootEntity entity = gson.fromJson(jsonText, RootEntity.class);
        System.out.println(entity);
        entity.setName("Alex");
        entity.setV(150);
        String thenBack = gson.toJson(entity);
        System.out.println(thenBack);

    }
}

This will result in :

so.alpha.TestGson$Foo@4b85612c
StructuredRoot [v=123, name=mario]

Still I don't understand why you would extend the Api class.

3
  • 1
    It was convenient to serialize because I can call toJson method using the extending class.
    – greywolf82
    Commented Jun 7, 2017 at 17:35
  • So, was this an answer or have I misunderstood what you were trying to achieve?
    – minus
    Commented Jun 7, 2017 at 18:01
  • Your code is quite good to deserialize but I want to serialize calling toJson
    – greywolf82
    Commented Jun 7, 2017 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.