Gson - setting an object reference on the fly using InstanceCreator

I am stuck in a problem when I need to set a reference to my object processed by its children during deserialization using Gsonand InstanceCreator.

To illustrate the problem, the following is a simple representation of the structure of classes.

public class Workshift {
    private final transient Context context;
    private final Visit visit;

    public Workshift(Context context) {
        this.context = context;
        this.visit = new Visit(this);
    }
}

public class Visit {
    private final transient Workshift workshift;

    public Visit(Workshift ws) {
        this.workshift = ws;
    }
}

In this structure, I can install Contextin Workshift, providing InstanceCreatorfor mine GsonBuilder, for example:

Gson gson = new GsonBuilder()
    .registerTypeAdapter(Workshift.class, new InstanceCreator<Workshift>() {
        @Override
        public Workshift createInstance(Type type) {
            return new Workshift(context);
        }
    })
    .create();

I know, I can add extra InstanceCreatorto mine GsonBuilder, but I'm not sure how to provide a link to my object Workshift, which is in the process of analysis (on the fly) before the object Visit?

Any help would be appreciated!

+3
2

GraphAdapterBuilder.

@Braj,

workhift - , . , -

.

Workshift.java

public class Workshift {
    private final transient Context context;
    private final Visit visit;
    //for testing
    private String workshift_description;

    public Workshift(Context context,String id) {
        this.workshift_description=id;
        this.context = context;
        this.visit = new Visit(this);

    }
    public String getId() {
        return workshift_description;
    }

    public void setId(String id) {
        this.workshift_description = id;
    }
    public String toString() {
        return "[Workshift element => { WD: "+this.workshift_description+", VD : "+this.visit.getVisit_description()+"}";
    }
}

Visit.java

public class Visit {

    private final /* transient  */ Workshift workshift;

    public Visit(Workshift ws) {
        this.workshift = ws;

    }
    public String getVisit_description() {
        return "visit containing  "+ workshift.getId();
    }

}

:

GsonBuilder gsonBuilder = new GsonBuilder();
        new GraphAdapterBuilder()
        .addType(Visit.class)
        .addType(Workshift.class)
        .registerOn(gsonBuilder);

,

public static void main(String[] args) {

        Workshift[] workshifts = new Workshift[10];
        for (int i = 0; i < workshifts.length; i++) {
            //Replace Context(i) for the real one
            workshifts[i] = new Workshift(new Context(i), "Workshift#"
                    + i);
        }
        System.out.println("Original Workshifts array:");
        for (int i = 0; i < workshifts.length; i++) {
            System.out.println(workshifts[i]);
        }
        System.out.println("===================================");

        GsonBuilder gsonBuilder = new GsonBuilder();
        new GraphAdapterBuilder()
        .addType(Visit.class)
        .addType(Workshift.class)
        .registerOn(gsonBuilder);

        Gson gson = gsonBuilder.setPrettyPrinting().create();
        String serialized = gson.toJson(workshifts);
        // System.out.println(serialized);
        Workshift[] w_array = gson.fromJson(serialized, Workshift[].class);
        // System.out.println(gson.toJson(w_array));

        System.out.println("Des-serialized Workshifts array:");
        for (int i = 0; i < w_array.length; i++) {
            System.out.println(w_array[i]);
        }
        System.out.println("===================================");

:

Original Workshifts array:
[Workshift element => { WD: Workshift#0, VD : visit containing  Workshift#0}
[Workshift element => { WD: Workshift#1, VD : visit containing  Workshift#1}
[Workshift element => { WD: Workshift#2, VD : visit containing  Workshift#2}
[Workshift element => { WD: Workshift#3, VD : visit containing  Workshift#3}
[Workshift element => { WD: Workshift#4, VD : visit containing  Workshift#4}
[Workshift element => { WD: Workshift#5, VD : visit containing  Workshift#5}
[Workshift element => { WD: Workshift#6, VD : visit containing  Workshift#6}
[Workshift element => { WD: Workshift#7, VD : visit containing  Workshift#7}
[Workshift element => { WD: Workshift#8, VD : visit containing  Workshift#8}
[Workshift element => { WD: Workshift#9, VD : visit containing  Workshift#9}
===================================
Des-serialized Workshifts array:
[Workshift element => { WD: Workshift#0, VD : visit containing  Workshift#0}
[Workshift element => { WD: Workshift#1, VD : visit containing  Workshift#1}
[Workshift element => { WD: Workshift#2, VD : visit containing  Workshift#2}
[Workshift element => { WD: Workshift#3, VD : visit containing  Workshift#3}
[Workshift element => { WD: Workshift#4, VD : visit containing  Workshift#4}
[Workshift element => { WD: Workshift#5, VD : visit containing  Workshift#5}
[Workshift element => { WD: Workshift#6, VD : visit containing  Workshift#6}
[Workshift element => { WD: Workshift#7, VD : visit containing  Workshift#7}
[Workshift element => { WD: Workshift#8, VD : visit containing  Workshift#8}
[Workshift element => { WD: Workshift#9, VD : visit containing  Workshift#9}
===================================

StackOverflow.

// System.out.println(serialized);

:

[
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#0"
    },
    "0x2": {
      "workshift": "0x1"
    }
  },
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#1"
    },
    "0x2": {
      "workshift": "0x1"
    }
  },
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#2"
    },
    "0x2": {
      "workshift": "0x1"
    }
  },
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#3"
    },
    "0x2": {
      "workshift": "0x1"
    }
  },
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#4"
    },
    "0x2": {
      "workshift": "0x1"
    }
  },
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#5"
    },
    "0x2": {
      "workshift": "0x1"
    }
  },
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#6"
    },
    "0x2": {
      "workshift": "0x1"
    }
  },
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#7"
    },
    "0x2": {
      "workshift": "0x1"
    }
  },
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#8"
    },
    "0x2": {
      "workshift": "0x1"
    }
  },
  {
    "0x1": {
      "visit": "0x2",
      "workshift_description": "Workshift#9"
    },
    "0x2": {
      "workshift": "0x1"
    }
  }

]

, Gson , .

, .

. GraphAdapterBuilder.java

private final ConstructorConstructor constructorConstructor = new ConstructorConstructor();

private final ConstructorConstructor constructorConstructor = new ConstructorConstructor(instanceCreators);

. , .

+1

:

workhift .

:

workhift Visit, , .

, , setter workhift .

, . , .

Visit.java:

public class Visit {
    private final transient Workshift workshift;

    public Visit() {

    }

    public Workshift getWorkshift() {
        return workshift;
    }

    public void setWorkshift(Workshift workshift) {
        this.workshift = workshift;
    }

}

JsonDeserializer, .

:

import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Type;

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 GSON {

        /**
         * @param args
         * @throws IOException
         * @throws ClassNotFoundException
         */
        public static void main(String[] args) throws Exception {
            // serialize
            Gson gson = new Gson();
            String json = gson.toJson(new Workshift());
            System.out.println("Workshift JSON:" + json);

            // deserialize
            GsonBuilder builder = new GsonBuilder();
            builder.registerTypeAdapter(Workshift.class, new WorkshiftDeserializer());

            Workshift workshift = builder.create().fromJson(json, Workshift.class);
            System.out.println("Reference of Workshift from Visit:"
                    + workshift.getVisit().getWorkshift());

        }

    }

    class Workshift implements Serializable {
        private Visit visit;

        public Workshift() {
            this.visit = new Visit(this);
        }

        public Visit getVisit() {
            return visit;
        }

        public void setVisit(Visit visit) {
            this.visit = visit;
        }

    }

    class Visit implements Serializable {
        private transient Workshift workshift;

        public Visit() {

        }

        public Visit(Workshift ws) {
            this.workshift = ws;
        }

        public Workshift getWorkshift() {
            return workshift;
        }

        public void setWorkshift(Workshift workshift) {
            this.workshift = workshift;
        }

    }


    class WorkshiftDeserializer implements JsonDeserializer<Workshift> {
        public Workshift deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                throws JsonParseException {

            Gson gson = new Gson();

            Workshift workshift = gson.fromJson(json, Workshift.class);
            workshift.getVisit().setWorkshift(workshift);
            return workshift;
        }
    }
0

All Articles