简体   繁体   中英

OffsetDateTime deserialization using Gson

I have a JSON with date-time attribute in the format

"1980-01-31T00:00:00+01:00"

,which I want to deserialize into org.threeten.bp.OffsetDateTime using Gson library,however I get following error :

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING

I tried following ,but now getting NumberFormatException:

Gson gSonInstance = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).setPrettyPrinting().
                registerTypeAdapter(OffsetDateTime.class, (JsonDeserializer<OffsetDateTime>) (json, type, jsonDeserializationContext) -> {
                   return   DateTimeUtils.
                            toInstant(new Date(json.getAsJsonPrimitive().getAsLong())).atZone(ZoneId.systemDefault()).toOffsetDateTime();
                }).create();

Unable to reproduce IllegalStateException

Posting this as an answer, so I can include Minimal, Reproducible Example of what I tried:

import java.util.Date;

import org.threeten.bp.DateTimeUtils;
import org.threeten.bp.OffsetDateTime;
import org.threeten.bp.ZoneId;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializer;

public class Test {
    public static void main(String[] args) throws Exception {
        Gson gSonInstance = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).setPrettyPrinting().
                registerTypeAdapter(OffsetDateTime.class, (JsonDeserializer<OffsetDateTime>) (json, type, jsonDeserializationContext) -> {
                    return   DateTimeUtils.
                            toInstant(new Date(json.getAsJsonPrimitive().getAsLong())).atZone(ZoneId.systemDefault()).toOffsetDateTime();
                }).create();

        Foo foo = gSonInstance.fromJson("{ \"bar\": \"1980-01-31T00:00:00+01:00\" }", Foo.class);
        System.out.println(foo.getBar());
    }
}

class Foo {
    private OffsetDateTime bar;
    public OffsetDateTime getBar() {
        return this.bar;
    }
    public void setBar(OffsetDateTime bar) {
        this.bar = bar;
    }
}

Output

Exception in thread "main" java.lang.NumberFormatException: For input string: "1980-01-31T00:00:00+01:00"
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
    at java.base/java.lang.Long.parseLong(Long.java:699)
    at java.base/java.lang.Long.parseLong(Long.java:824)
    at com.google.gson.JsonPrimitive.getAsLong(JsonPrimitive.java:242)
    at Test.lambda$0(Test.java:17)
    at com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
    at com.google.gson.Gson.fromJson(Gson.java:927)
    at com.google.gson.Gson.fromJson(Gson.java:892)
    at com.google.gson.Gson.fromJson(Gson.java:841)
    at com.google.gson.Gson.fromJson(Gson.java:813)
    at Test.main(Test.java:20)

That error is of course expected, since you're calling json.getAsJsonPrimitive().getAsLong() when the json value is a string.


UPDATE

To fix that, change code to:

Gson gSonInstance = new GsonBuilder()
        .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
        .setPrettyPrinting()
        .registerTypeAdapter(OffsetDateTime.class, (JsonDeserializer<OffsetDateTime>)
                (json, type, context) -> OffsetDateTime.parse(json.getAsString()))
        .create();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM