delita
delita

Reputation: 1581

How to serialize specific fields of an object?

I would like to serialize certain fields on an object. And during the deserialization process force to to re-construct the object by going thru the appropriate constructor. Is this possible ?

For Example:

public Person()
{
    private String name;
    private int age;
    private Person parent;

    void Person(String name, int age)
    {
        this.name = name;
        this.age = age;

        this.parent = new Person("Mom", 65);
    }
}

I would like to store the "name" and "age" fields of person. And when deserializing, to call the constructor and re-create the parent object.

Upvotes: 3

Views: 481

Answers (3)

Low Flying Pelican
Low Flying Pelican

Reputation: 6054

xstream does support using constructors other than default one in the enhanced mode.

http://x-stream.github.io/index.html

Upvotes: 1

Vic Fryzel
Vic Fryzel

Reputation: 2395

You can do this using Gson to serialize and deserialize objects to and from a JSON representation. Gson has built in serializers and deserializers that are capable of handling generic objects, but if you require something special, then you can implement your own. In the example mentioned in the question, the generic serializers and deserializers would probably work if the class had a constructor with no arguments.

The simple way to do what you need is as follows:

public class Person {
  private String name;
  private int age;
  private Person parent = null;

  public Person() {
    // Required no-args constructor for Gson.
  }

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
}

Serialization

Person joe = new Person("Joe", 20);
Gson gson = new Gson();
String json = gson.toJson(joe);  
==> json is {"name":"Joe","age":"20"}

Note that you can not serialize objects with circular references since that will result in infinite recursion. Also, the example provided in the question would not be possible, as parents would be instantiated indefinitely.

Deserialization

Person joe = gson.fromJson(json, Person.class);

If you need something more custom than this, you can use custom serialization and deserialization. From the user guide:

Custom Serialization and Deserialization

Sometimes default representation is not what you want. This is often the case when dealing with library classes (DateTime, etc). Gson allows you to register your own custom serializers and deserializers. This is done by defining two parts: Json Serialiers: Need to define custom serialization for an object Json Deserializers: Needed to define custom deserialization for a type Instance Creators: Not needed if no-args constructor is available or a deserializer is registered

GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(MyType2.class, new MyTypeAdapter());
gson.registerTypeAdapter(MyType.class, new MySerializer());
gson.registerTypeAdapter(MyType.class, new MyDeserializer());
gson.registerTypeAdapter(MyType.class, new MyInstanceCreator());

registerTypeAdapter call checks if the type adapter implements more than one of these interfaces and register it for all of them.

Writing a Serializer

Here is an example of how to write a custom serializer for JodaTime DateTime class.

private class DateTimeSerializer implements JsonSerializer<DateTime> {
  public JsonElement serialize(DateTime src, Type typeOfSrc,
      JsonSerializationContext context) {
    return new JsonPrimitive(src.toString());
  }
}

Gson calls toJson() when it runs into a DateTime object during serialization.

Writing a Deserializer

Here is an example of how to write a custom deserializer for JodaTime DateTime class.

private class DateTimeDeserializer implements
    JsonDeserializer<DateTime> {
  public DateTime deserialize(JsonElement
      json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    return new DateTime(json.getAsJsonPrimitive().getAsString());
  }
}

Gson calls fromJson() when it needs to deserialize a JSON string fragment into a DateTime object

Upvotes: 0

dash1e
dash1e

Reputation: 7807

If you change your class Person so that it implements Serializable then you can simply use Java serialization features. And the deserialization process will recreates all the object hierarchy.

You don't need any other library if your task is simply serialize and store that class.

Here a simple article on Java serialization.

Upvotes: 0

Related Questions