1

In my java project there is a gson deserializer function which results the following error.

java.lang.NumberFormatException: For input string: "2017-01-28 13:28:20"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.parseLong(Long.java:631)
at com.google.gson.JsonPrimitive.getAsLong(JsonPrimitive.java:238)
at com.example.myproject.controller.MyController$1.deserialize(MyController.java:222)
at com.example.myproject.controller.MyController$1.deserialize(MyController.java:1)
at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
at com.google.gson.internal.bind.TypeAdapters$22$1.read(TypeAdapters.java:526)
at com.google.gson.internal.bind.TypeAdapters$22$1.read(TypeAdapters.java:524)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
at com.google.gson.Gson.fromJson(Gson.java:803)
at com.google.gson.Gson.fromJson(Gson.java:768)
at com.google.gson.Gson.fromJson(Gson.java:717)
at com.google.gson.Gson.fromJson(Gson.java:689)

I am getting this error when i deserialize the below json string.

jsonString = {"repList":[{"createdOn":"2017-01-28 13:28:20","date":"2016-11-17 00:00:00","description":"","id":45,"userId":10}],"subList":[{"attachmentCount":0,"dateOn":"2017-01-28 13:28:20","id":86,"screenId":1,"sync":"1","repId":45,"userId":10}]}

Below is my function where i have done the gson deserialization.

SimpleDateFormat dtf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.ENGLISH);
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {

    @Override
    public Date deserialize(JsonElement json, Type type, JsonDeserializationContext deserializationContext) throws JsonParseException {

        String frStr = dtf.format(new Date(json.getAsJsonPrimitive().getAsLong()));
        dtf.setTimeZone(TimeZone.getDefault());
        Date retDate =null;
            try {
                retDate = dtf.parse(frStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        return retDate;
    }
});
gson = builder.create();
MainAccounts mainAcc = gson.fromJson(jsonString, MainAccounts.class);

What I noticed is the exception comes when i convert the json primitive to long as below

json.getAsJsonPrimitive().getAsLong()

inside the deserialize method.How can i solve this?Please help me.

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
KJEjava48
  • 1,967
  • 7
  • 40
  • 69

2 Answers2

3

You need to get directly the value of your JsonElement as it really is: a String not a long by calling the method getAsString() otherwise you will get a NumberFormatException as you already have noticed, so your JsonDeserializer should rather be:

new JsonDeserializer<Date>() {
    private SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    {
        // Indicate the time zone of the input date
        dtf.setTimeZone(TimeZone.getTimeZone("Asia/Dubai"));
    }
    @Override
    public Date deserialize(JsonElement json, Type type, 
        JsonDeserializationContext deserializationContext) throws JsonParseException {
        try {
            // Get the json element as a String and parse it to get a Date
            return dtf.parse(json.getAsString());
        } catch (ParseException e) {
            // Throw a JsonParseException in case of a parsing error
            throw new JsonParseException(e);
        }
    }
}

NB: As it is, the anonymous inner class of type JsonDeserializer proposed above is not thread-safe because of SimpleDateFormat that is itslef not thread-safe so avoid sharing an instance of it, create a new instance anytime you want to deserialize your JSON Content.

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
  • ok.its working now.Also the above json string comes with date values are corresponding to dubai timezone,now i need to convert its to server timezone(that is in india) so the date value changes to indian time.How can i do this along with the format? – KJEjava48 Jan 28 '17 at 10:40
  • @KJEjava48 what matters while parsing is the input time zone as a `java.util.Date` is timezone-independent (it is actually a timestamp in UTC), check [this](http://stackoverflow.com/questions/1516213/is-java-util-date-using-timezone) for more details. See also http://stackoverflow.com/questions/7670355/convert-date-time-for-given-timezone-java – Nicolas Filotto Jan 28 '17 at 11:16
  • @LyubomyrShaydariv that's right, it is not meant to be shared so it is not really an issue but indeed I should mention it – Nicolas Filotto Jan 28 '17 at 19:52
  • @NicolasFilotto I didn't understood what u r telling.Does i need to create a class for above json serialization and deserialization and use this class with the GsonBuilder?? – KJEjava48 Jan 30 '17 at 06:41
  • In your code when you call the method registerTypeAdapter, the first parameter is Date.class, the anonymous inner class proposed in my answer should be the second parameter – Nicolas Filotto Jan 30 '17 at 07:32
2

I assume the problem is that the value is not a String that represents a long, so you can't parse it as such. You should probably use String frStr = dtf.parse(json.getAsJsonPrimitivie().getAsString())