BillB
BillB

Reputation: 37

Error "gson.JsonSyntaxException" when I try to retrieve a document with a date in MongoDB

In my MongoDB databse there are documents with a date field. By making a console find the result looks like:

"data" : ISODate("2015-03-01T00:40:45Z")

But when GSON try to retrieve the object appears this error:

javax.servlet.ServletException: com.google.gson.JsonSyntaxException: 03-01-2015-01-40-45-000

I tried to use the GSONBuilder as described below but the error persists:

Gson gson=  new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssX").create();

How can I fix this?

Upvotes: 0

Views: 2449

Answers (4)

Mugeesh Husain
Mugeesh Husain

Reputation: 428

 Employee employee = new GsonBuilder()
            .registerTypeAdapter(LocalTime.class, new MyDateTypeAdapter())
            .create().fromJson(json, Employee.class);

Change Locatime to Date orDatetime as per your requirement.

public class MyDateTypeAdapter implements JsonDeserializer<LocalTime> {

@Override
public synchronized LocalTime deserialize(JsonElement jsonElement, Type type,
                                          JsonDeserializationContext jsonDeserializationContext) {
    try {
        JsonPrimitive dateStr= jsonElement.getAsJsonObject().getAsJsonPrimitive("$date") ;
        Instant instant = Instant.parse(dateStr.getAsString());
        LocalTime localTime = LocalTime.ofInstant(instant, ZoneId.of(ZoneOffset.UTC.getId()));
        return localTime;
    } catch (Exception e) {
        log.error("error calling deserialize {}", e);
        throw new JsonParseException(e);
    }
}

}

Upvotes: 1

user1114134
user1114134

Reputation: 608

Updated long time = json.getAsJsonObject().getAsJsonPrimitive("$date").getAsLong();

 import com.google.gson.JsonDeserializationContext;
 import com.google.gson.JsonDeserializer;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonParseException;
 import java.lang.reflect.Type;
 import java.util.Date;

 public class JsonDateDeserializer implements JsonDeserializer<Date> {
      public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
           long time = json.getAsJsonObject().getAsJsonPrimitive("$date").getAsLong();
           Date d = new Date(time);
           return d;
      }
 }

http://www.techiesinfo.com/performance

Upvotes: 1

bancomat
bancomat

Reputation: 15

I receive from server a Json Object with a long value (Timestamp) for Date.

I am creating my Gson object:

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

This is code for my JsonDateDeserializer:

 import com.google.gson.JsonDeserializationContext;
 import com.google.gson.JsonDeserializer;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonParseException;
 import java.lang.reflect.Type;
 import java.util.Date;

    public class JsonDateDeserializer implements JsonDeserializer<Date> {
    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        long time = json.getAsJsonPrimitive().getAsLong();
        Date d = new Date(time);
        return d;
    }
}

Upvotes: 1

user3655614
user3655614

Reputation: 56

I'm also using Gson to deserialize JSON string. For me, none of the following formats worked:

setDateFormat("yyyy-MM-dd'T'HH:mm:ssX").create();  //Didn't work
setDateFormat("yyyy-MM-dd'T'HH:mm:ssz").create();  //Didn't work
setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create();  //Didn't work

Each of them was failing to parse the date. So I just removed the last character from the format. And it worked.

setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create();  //worked

I know this is not the correct way, but at least it allows you to parse the date for the time being.

Edit: There is a better solution at this link Gson: JsonSyntaxException on date. Basically, this is the gist of the answer there:

I created a custom JsonDeserializer and registered it for the Date type. By doing so, Gson will use my deserializer for the Date type instead of its default. The same can be done for any other type if you want to serialize/deserialize it in a custom way.

public class JsonDateDeserializer implements JsonDeserializer<Date> {
   public Date deserialize(JsonElement json, Type typeOfT,JsonDeserializationContext context) throws JsonParseException {
      String s = json.getAsJsonPrimitive().getAsString();
      long l = Long.parseLong(s.substring(6, s.length() - 2));
      Date d = new Date(l);
      return d; 
   } 
}

Then, when I am creating my Gson object:

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

EDIT 2: Turns out that the logic in the deserialize() function above did not work properly. So decided to use Joda-Time library. Here is the modified function:

public class JsonDateDeserializer implements JsonDeserializer<Date> {
  public Date deserialize(JsonElement json, Type typeOfT,JsonDeserializationContext context) throws JsonParseException {
    String s = json.getAsJsonPrimitive().getAsString();
    DateTimeFormatter parser    = ISODateTimeFormat.dateTimeParser();
    DateTime dateTime = parser.parseDateTime(s);
    return dateTime.toDate();
  }
}

This is working. :)

So basically, either use the very first option, or use the last option here.

Upvotes: 0

Related Questions