Rest 以毫秒为单位转换日期时发生GSON DateTypeException

Rest 以毫秒为单位转换日期时发生GSON DateTypeException,rest,gson,Rest,Gson,我有一个Contact类,它具有一个创建的日期属性。我正在尝试执行以下操作: Contact received = gson.fromJson(contactJson, Contact.class); 但是我得到了一个例外: com.google.gson.JsonSyntaxException: 1433444958703 at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapt

我有一个Contact类,它具有一个
创建的
日期属性。我正在尝试执行以下操作:

    Contact received = gson.fromJson(contactJson, Contact.class);
但是我得到了一个例外:

 com.google.gson.JsonSyntaxException: 1433444958703
at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:81)
at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:66)
对此已发布了类似的解决方案:

但是它对我不起作用(不会编译)

Gson版本2.3.1

想法

蒂亚,
-Ole在此处()找到了类似的解决方案,并对其进行了微调:

class JsonDateDeserializer
    implements JsonDeserializer<Date> {

    public Date deserialize(JsonElement json,
                            Type date,
                            JsonDeserializationContext context)
        throws JsonParseException {
        String stringDate = json.getAsJsonPrimitive().getAsString();
        return new Date(Long.parseLong(stringDate));
    }
}

Gson gson =
    new GsonBuilder().registerTypeAdapter(Date.class,
                                          new JsonDateDeserializer())
        .create();
类JsonDateDeserializer
实现JsonDeserializer{
公共日期反序列化(JsonElement json,
键入日期,
JsonDeserializationContext(上下文)
抛出JsonParseException{
字符串stringDate=json.getAsJsonPrimitive().getAsString();
返回新日期(Long.parseLong(stringDate));
}
}
格森格森=
新建GsonBuilder().registerTypeAdapter(Date.class,
新的JsonDateDeserializer())
.create();

这很有效。如果这是GSON中的默认值,那就太好了:)。

您可以编写一个简单的类型适配器,并将其注册到GsonBuilder实例,或者在Contact类本身中使用@JsonAdapter进行注释。请注意,您应该将日期序列化为长字符串,因为long不是有效的JSON类型,并且可能会被修剪为int(对于大多数日期,这肯定会失败)

以下是适配器的外观:

public class LongDateTypeAdapter extends TypeAdapter<Date> {
  @Override public void write(JsonWriter out, Date value) throws IOException {
    if (value == null) {
      out.nullValue();
    } else {
      out.value(String.valueOf(value.getTime()));
    }
  }
  @Override public Date read(JsonReader in) throws IOException {
    switch (in.peek()) {
    case NULL: return null;
    case STRING: 
      try {
        return new Date(Long.parseLong(in.nextString()));
      } catch (NumberFormatException e) {
        throw new JsonSyntaxException(e);
      }
    default: throw new JsonSyntaxException("invalid date" + in.getPath());
    }
  }
}
公共类LongDateTypeAdapter扩展了TypeAdapter{
@重写公共void write(JsonWriter out,日期值)引发IOException{
如果(值==null){
out.nullValue();
}否则{
out.value(String.valueOf(value.getTime());
}
}
@重写公共日期读取(JsonReader in)引发IOException{
开关(in.peek()){
case NULL:返回NULL;
大小写字符串:
试一试{
返回新日期(Long.parseLong(in.nextString());
}捕获(数字格式){
抛出新的JsonSyntaxException(e);
}
默认值:抛出新的JsonSyntaxException(“无效日期”+in.getPath());
}
}
}
您可以在以下位置查看源代码:

以下是说明如何使用它的测试:

Hello@inder123感谢您指出替代解决方案。我们是否可以为构建器添加一个简单的选项来进行searialization,指定Spring引导在异常中列出的三个标准表单之一?(\“yyyy-MM-dd'T'HH:MM:ss.SSSZ\”\“yyy-MM-dd'HH:MM:ss-zzz'\“yyyy-MM-dd\”)如果GSON有一个更智能的反序列化,反映Spring引导编组的反序列化,并且可能还合并了来自其他框架的格式,那就太好了。@user1684269您应该使用GsonBuilder.setDateFormat()用你选择的图案。