Q:

Parsing object containing date using GSON - Unparseable date

I have the following JSON data -
[
    {
        "Name": "Litware, Inc. (sample)",
        "__type": "CRMService.Account",
        "Status": 0,
        "Owner": "abijeet patro",
        "AccountID": "e5259a52-672f-e311-a7d8-d89d6765b134",
        "RelationshipType": "Customer",
        "Latitude": 32.85424041748047,
        "LastActivity": {
            "__type": "CRMService.Activity",
            "Subject": "Testing",
            "Type": "Phone Call",
            "RegardingObjectType": "account",
            "RegardingObjectId": "e5259a52-672f-e311-a7d8-d89d6765b134",
            "EndTime": "/Date(1382898600000)/",
            "Id": "b3cb43e1-963f-e311-9990-d89d676560dc",
            "StartTime": "/Date(1382898600000)/"
        },
        "PhoneNumber": null,
        "Longitude": -96.61327362060547,
        "OwnerID": "975504fb-cb94-498a-816c-6c3a5c62465a"
    },
    {
        "Name": "A. Datum Corporation (sample)",
        "__type": "CRMService.Account",
        "Status": 0,
        "Owner": "abijeet patro",
        "AccountID": "f3259a52-672f-e311-a7d8-d89d6765b134",
        "RelationshipType": "Supplier",
        "Latitude": 0,
        "LastActivity": {
            "__type": "CRMService.Activity",
            "Subject": "Call back to understand the problem (sample)",
            "Type": "Phone Call",
            "RegardingObjectType": "account",
            "RegardingObjectId": "f3259a52-672f-e311-a7d8-d89d6765b134",
            "EndTime": "/Date(1381226400000)/",
            "Id": "50b79458-672f-e311-a7d8-d89d6765b134",
            "StartTime": "/Date(1381226400000)/"
        },
        "PhoneNumber": null,
        "Longitude": 0,
        "OwnerID": "975504fb-cb94-498a-816c-6c3a5c62465a"
    },
    {
        "Name": "Coho Winery (sample)",
        "__type": "CRMService.Account",
        "Status": 0,
        "Owner": "abijeet patro",
        "AccountID": "f5259a52-672f-e311-a7d8-d89d6765b134",
        "RelationshipType": "Investor",
        "Latitude": 0,
        "LastActivity": null,
        "PhoneNumber": null,
        "Longitude": 0,
        "OwnerID": "975504fb-cb94-498a-816c-6c3a5c62465a"
    }
]

I'm trying to parse it into the following Java class(es) - 
public class CRMAccount {
    private String AccountID;
    private String CRMId;
    private String Name;
    private CRMActivity LastActivity;
    private String Owner;
    private double Latitude;
    private double Longitude;
    private String AppointmentType;
    private String RelationshipType;
    private int Status;

    public String getID() {
        return AccountID;
    }

    public void setID(String accountID) {
        AccountID = accountID;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public CRMActivity getLastActivity() {
        return LastActivity;
    }

    public void setLastActivity(CRMActivity lastActivity) {
        LastActivity = lastActivity;
    }

    public String getOwner() {
        return Owner;
    }

    public void setOwner(String owner) {
        Owner = owner;
    }

    public String getAppointmentType() {
        return AppointmentType;
    }

    public void setAppointmentType(String appointmentType) {
        AppointmentType = appointmentType;
    }

    public String getRelationshipType() {
        return RelationshipType;
    }

    public void setRelationshipType(String relationshipType) {
        RelationshipType = relationshipType;
    }

    public double getLatitude() {
        return Latitude;
    }

    public void setLatitude(double latitude) {
        Latitude = latitude;
    }

    public double getLongitude() {
        return Longitude;
    }

    public void setLongitude(double longitude) {
        Longitude = longitude;
    }

    public String getCRMId() {
        return CRMId;
    }

    public void setCRMId(String cRMId) {
        CRMId = cRMId;
    }
}

public class CRMActivity {
    private String Type;
    private String Subject;
    private String RegardingObjectType;
    private Date StartTime;
    private Date EndTime;

    public CRMActivity(String type, Date dtEndTime,
            Date dtStartTime, String subject)
    {
        this.Type = type;
        this.Subject = subject;
        this.StartTime = dtStartTime;
        this.EndTime = dtEndTime;
        this.RegardingObjectType = "account";       
    }

    public String getType() {
        return Type;
    }
    public void setType(String eventType) {
        Type = eventType;
    }

    public String getSubject() {
        return Subject;
    }
    public void setSubject(String subject) {
        Subject = subject;
    }

    public String getRegardingObject()
    {
        return RegardingObjectType;
    }

    public Date getStartTime() {
        return StartTime;
    }
    public void setStartTime(Date startTime) {
        StartTime = startTime;
    }

    public Date getEndTime() {
        return EndTime;
    }
    public void setEndTime(Date endTime) {
        EndTime = endTime;
    }   
}

This is the code I'm using to parse the JSON data -
    Gson gson = new GsonBuilder().setDateFormat(DateFormat.FULL, DateFormat.FULL).create();
    CRMAccount[] lstCRMAccounts = gson.fromJson(serviceResponse.getResultMessage(),CRMAccount[].class); 

This is the output from LogCat -
10-29 17:00:40.073: E/AndroidRuntime(17524): FATAL EXCEPTION: main
10-29 17:00:40.073: E/AndroidRuntime(17524): com.google.gson.JsonSyntaxException: /Date(1382898600000)/
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:81)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:66)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:41)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:72)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.Gson.fromJson(Gson.java:803)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.Gson.fromJson(Gson.java:768)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.Gson.fromJson(Gson.java:717)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.Gson.fromJson(Gson.java:689)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at osm.droid.mat.services.SyncService.OnTaskComplete(SyncService.java:97)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at osm.droid.mat.async.CallWebService.onPostExecute(CallWebService.java:70)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at osm.droid.mat.async.CallWebService.onPostExecute(CallWebService.java:1)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at android.os.AsyncTask.finish(AsyncTask.java:602)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at android.os.AsyncTask.access$600(AsyncTask.java:156)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at android.os.Handler.dispatchMessage(Handler.java:99)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at android.os.Looper.loop(Looper.java:154)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at android.app.ActivityThread.main(ActivityThread.java:4624)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at java.lang.reflect.Method.invokeNative(Native Method)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at java.lang.reflect.Method.invoke(Method.java:511)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at dalvik.system.NativeStart.main(Native Method)
10-29 17:00:40.073: E/AndroidRuntime(17524): Caused by: java.text.ParseException: Unparseable date: "/Date(1382898600000)/" (at offset 0)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at java.text.DateFormat.parse(DateFormat.java:626)
10-29 17:00:40.073: E/AndroidRuntime(17524):    at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:79)

A:

I would use a custom deserializer, due to the problem that you have with date parsing, and also since you class has not a parameterless constructor. I limited my example only to the CRMActivity class.
public class CustomDeserializer implements JsonDeserializer<CRMActivity> {

    public CRMActivity deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context) throws JsonParseException {

        if (json == null)
            return null;

        JsonObject jo = json.getAsJsonObject();

        String type = jo.get("Type").getAsString();
        String subject = jo.get("Subject").getAsString();
        String endTimeAsString = jo.get("EndTime").getAsString();
        String startTimeAsString = jo.get("StartTime").getAsString();

        startTimeAsString = startTimeAsString.replace("/Date(", "").replace(")/", "");
        endTimeAsString = endTimeAsString.replace("/Date(", "").replace(")/", "");

        return new CRMActivity(type, new Date(Long.valueOf(startTimeAsString)),
                new Date(Long.valueOf(endTimeAsString)), subject);

    }

and call it this way:
public class Q19657666 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        GsonBuilder gb = new GsonBuilder();
        gb.registerTypeAdapter(CRMActivity.class, new CustomDeserializer());

        Gson g = gb.create();

        String json = "{\"__type\": \"CRMService.Activity\","+
        "\"Subject\": \"Call back to understand the problem (sample)\", "+
        "\"Type\": \"Phone Call\", "+
        "\"RegardingObjectType\": \"account\","+
        "\"RegardingObjectId\": \"f3259a52-672f-e311-a7d8-d89d6765b134\","+
        "\"EndTime\": \"/Date(1381226400000)/\","+
        "\"Id\": \"50b79458-672f-e311-a7d8-d89d6765b134\","+
        "\"StartTime\": \"/Date(1381226400000)/\"}";

        CRMActivity crmActivity = g.fromJson(json, CRMActivity.class);

        System.out.println(crmActivity);
    }

}

You'll get this result:

CRMActivity [Type=Phone Call, Subject=Call back to understand the
  problem (sample), RegardingObjectType=account, StartTime=Tue Oct 08
  12:00:00 CEST 2013, EndTime=Tue Oct 08 12:00:00 CEST 2013]

