Gson: JsonSyntaxException on date

2022-09-03 16:59:56

我正在尝试使用Gson来反序列化json数组,但目前我得到了一个JsonSyntaxException。json字符串是由使用JsonResult的.NET MVC3 Web服务创建的(这意味着,我不是手动创建json,它是由我知道可以在其他几个平台上工作的库创建的)。

这是 json:

[{"PostID":1,"StudentID":39,"StudentName":"Joe Blow",
"Text":"Test message.","CreateDate":"\/Date(1350178408267)\/",
"ModDate":"\/Date(1350178408267)\/","CommentCount":0}]

这是代码:

public class Post {
   public int PostID;
   public int StudentID;
   public String StudentName;
   public String Text;
   public Date CreateDate;
   public Date ModDate;

   public Post() { }
}

Type listOfPosts = new TypeToken<ArrayList<Post>>(){}.getType();
ArrayList<Post> posts = new Gson().fromJson(json, listOfPosts);

异常表明日期格式无效:

com.google.gson.JsonSyntaxException: /Date(1350178408267)/

有人知道发生了什么吗?


答案 1

我在这里找到了答案,但我觉得很奇怪,没有更简单的方法。我使用过的其他几个 json 库本身支持 .NET json 格式。当Gson没有处理它时,我感到很惊讶。一定有更好的方法。如果有人知道,请在这里发布。尽管如此,这是我的解决方案:

我创建了一个自定义 JsonDeserializer 并将其注册为 Date 类型。通过这样做,Gson 将使用我的反序列化程序作为 Date 类型,而不是其默认值。如果要以自定义方式序列化/反序列化任何其他类型,也可以执行相同的操作。

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; 
   } 
}

然后,当我创建我的Gson对象时:

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

现在,我的 gson 对象将能够解析 .NET 日期格式(自 1970 年以来的 millis)。


答案 2

另一种解决方案是使用ISO 8601格式。这必须在Gson两侧配置为:

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

以及在服务器端,例如,对于文件中的 ASP.NET MVC,如下所示:Global.asax.cs

JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
serializerSettings.Converters.Add(new IsoDateTimeConverter());
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = serializerSettings;

上述代码的优点是它同时处理序列化和反序列化,因此允许双向传输日期/时间。

注意:类是 JSON.NET 库的一部分。IsoDateTimeConverter