2

I am using GSON library to serialize and deserialize java objects on both client and server sides. I have a scenario in which I have a date in milliseconds on the client, but on the server, I have same field with data type of Date. Here is the example code at the client end -

class Dog {
  long id;
  long purchaseDate; //This is in milliseconds
  String name;
  boolean status;
}

And on server side -

class Dog {
  long id;
  Date purchaseDate; //Convert milliseconds to date
  String name;
  int status; //If boolean is false then 0 else 1
}

How to do it using GSON library. If it is not possible through GSON, then which library will be suitable for this kind of serialization/ deserialization?

iagreen
  • 31,470
  • 8
  • 76
  • 90
Syed Hassan
  • 438
  • 4
  • 19

2 Answers2

6

You can use a custom TypeAdapter that converts longs in the JSON to Date in POJOs. You can use this on the server side, and then the client and JSON will use long, and the server will use Date.

public class DateTypeAdapter extends TypeAdapter<Date> {
  @Override
  public void write(JsonWriter out, Date value) throws IOException {
    out.value(value.getTime());
  }

  @Override
  public Date read(JsonReader in) throws IOException {
    return new Date(in.nextLong());
  }
}

You will need to use a custom Gson that registers the adapter. This will apply to the adapter to all fields with the type Date --

Gson gson = new GsonBuilder()
    .registerTypeAdapter(Date.class, new DateTypeAdapter())
    .create();

To only apply to specific fields, apply the adapter using the JsonAdapter annotation.

class Dog {
  long id;
  @JsonAdapter(DateTypeAdapter.class)
  Date purchaseDate; //Convert milliseconds to date
  String name;
  int status; //If boolean is false then 0 else 1
}

Note that with this invocation, you can use a regular gson ---

Gson gson = new Gson();
iagreen
  • 31,470
  • 8
  • 76
  • 90
  • This answer was very useful. I need some more clarification of it. I was wondering how will GSON will get to know which field has to use typeadapter. Because I have another field which is boolean on client side and int on server side. so how can I mention field name with its type adapter to use. – Syed Hassan Oct 22 '15 at 05:53
  • That is a good question -- my original answer applies the custom convertor to all `Date` types. I edited the answer to show how to apply to a specific field. boolean to int would be similar, except when dealing with primitives, you will need to make the object equivalent (Boolean or Integer) and define the adapter on Boolean or Integer as well. If you control both server and client, it is nice to keep the data model consistent if you can. Which means unless you have a compelling reason, you should probably make both status values booleans or both ints and skip the custom `TypeAdapter` – iagreen Oct 22 '15 at 06:22
  • Thanks a lot folk. This was the perfect answer I was looking for. – Syed Hassan Oct 22 '15 at 06:28
1

GSON library forms the object using reflection therefore converting long to Date will not be a feasible.

Have a look at this

Parsing object containing date using GSON - Unparseable date

I tried to see if I am able to have the date value parsed

Parsing date as it is has been a problem in the GSON api. Which gets resolved if you use a GSonBuilder but still having it converted from long does not sound plausible.

JavaDoc for SimpleDateFormat

    Gson gSon=  new GsonBuilder().setDateFormat("yyyy-MM-dd").create();

    detail = "{\"val\":\"2015-03-21\",\"name\":\"Name\"}";
    G2 g2obj = gSon.fromJson(detail, G2.class);

where G2 is the bean class

import java.util.Date;

public class G2 {
private Date val;
private String name;
public Date getVal() {
    return val;
}

public void setVal(String val) {
    this.val = new Date(new Long(val));
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}

}

BTW I even tried this

gSon= new GsonBuilder().setDateFormat("SSSSSSSSSSSSS").create();

This simply screws the date

{"val":1445467370920,"name":"Name","strVal":"Wed Oct 21 15:16:33 PDT 2015"}

G2 [val=Tue Dec 09 13:51:55 PST 1969, name=Name]

Above the time in milliseconds 1445467370920 is a Wed Oct 21 15:42:51 PDT 2015

Community
  • 1
  • 1
Acewin
  • 1,657
  • 4
  • 17
  • 36
  • You are right that it is not recommended to use milliseconds but there are some issues which enforce me to use this. Besides that there are other fields as i mentioned 'status' which is different on both ends. So anyhow i have to fix this issue. Thanks for iagreen who helped me doing it. – Syed Hassan Oct 22 '15 at 06:47