Java 使用Gson进行OffsetDateTime反序列化

Java 使用Gson进行OffsetDateTime反序列化,java,Java,我有一个格式为的带有日期时间属性的JSON “1980-01-31T00:00:00+01:00” ,我想 使用Gson库反序列化到org.threeten.bp.OffsetDateTime,但我得到以下错误: java.lang.IllegalStateException:应为BEGIN_对象,但为字符串 我尝试了以下操作,但现在得到NumberFormatException: Gson gSonInstance = new GsonBuilder().setFieldNamingPolic

我有一个格式为的带有日期时间属性的JSON

“1980-01-31T00:00:00+01:00”

,我想 使用Gson库反序列化到
org.threeten.bp.OffsetDateTime
,但我得到以下错误:

java.lang.IllegalStateException:应为BEGIN_对象,但为字符串

我尝试了以下操作,但现在得到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();
Gson gSonInstance=new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_,带下划线)。setPrettyPrinting()。
registerTypeAdapter(OffsetDateTime.class,(JsonDeserializer)(json,类型,jsonDeserializationContext)->{
返回日期timeutils。
toInstant(新日期(json.getAsJsonPrimitive().getAsLong()).atZone(ZoneId.systemDefault()).toOffsetDateTime();
}).create();

无法复制非法状态异常

将此作为答案发布,以便我可以包括我尝试的内容:

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;
    }
}
这个错误当然是意料之中的,因为当
json
值是字符串时,调用的是
json.getAsJsonPrimitive().getAsLong()


更新

要解决此问题,请将代码更改为:

Gson gSonInstance = new GsonBuilder()
        .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
        .setPrettyPrinting()
        .registerTypeAdapter(OffsetDateTime.class, (JsonDeserializer<OffsetDateTime>)
                (json, type, context) -> OffsetDateTime.parse(json.getAsString()))
        .create();
Gson gSonInstance=new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_,带下划线)
.setPrettyPrinting()
.registerTypeAdapter(OffsetDateTime.class,(JsonDeserializer)
(json,类型,上下文)->OffsetDateTime.parse(json.getAsString())
.create();

无法复制非法状态异常

将此作为答案发布,以便我可以包括我尝试的内容:

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;
    }
}
这个错误当然是意料之中的,因为当
json
值是字符串时,调用的是
json.getAsJsonPrimitive().getAsLong()


更新

要解决此问题,请将代码更改为:

Gson gSonInstance = new GsonBuilder()
        .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
        .setPrettyPrinting()
        .registerTypeAdapter(OffsetDateTime.class, (JsonDeserializer<OffsetDateTime>)
                (json, type, context) -> OffsetDateTime.parse(json.getAsString()))
        .create();
Gson gSonInstance=new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_,带下划线)
.setPrettyPrinting()
.registerTypeAdapter(OffsetDateTime.class,(JsonDeserializer)
(json,类型,上下文)->OffsetDateTime.parse(json.getAsString())
.create();

是的,同意,我改为getAsString,但仍然存在相同的错误。尝试将“return-DateTimeUtils.toInstant(新日期(json.getAsJsonPrimitive().getAsLong())).atZone(ZoneId.systemDefault()).toOffsetDateTime()替换为“return-ZoneDateTime.parse(json.getAsJsonPrimitive().getAsString(),).toOffsetDateTime();”。您能建议这里可以使用什么格式吗。@user2603985字符串不是原语。我的错误。这个字符串现在正在工作。“返回ZonedDateTime.parse(json.getAsString(),DateTimeFormatter.ISO_ZONED_DATE_TIME.)。toOffsetDateTime();”。谢谢。@Sudix它在问题代码中,所以您应该在那里问。是的,同意,我改为getAsString,但仍然出现相同的错误。尝试将“return-DateTimeUtils.toInstant(新日期(json.getAsJsonPrimitive().getAsLong())).atZone(ZoneId.systemDefault()).toOffsetDateTime();”替换为“return-ZoneDateTime.parse(json.getAsJsonPrimitive().getAsString(),).toOffsetDateTime();”。您能建议这里可以使用什么格式吗。@user2603985字符串不是原语。我的错误。这个字符串现在正在工作。“返回ZonedDateTime.parse(json.getAsString(),DateTimeFormatter.ISO_ZONED_DATE_TIME.)。toOffsetDateTime();”。谢谢。@Sudix它在问题代码中,所以您应该在那里提问。