Gson: JsonSyntaxException на дату

Я пытаюсь использовать Gson для десериализации массива json, но в настоящее время я получаю исключение JsonSyntaxException. Строка json была создана веб-службой .NET MVC3 с использованием JsonResult (что означает, что я не вручную создаю 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. Я был удивлен, когда он не справился с этим. Должен быть лучший способ. Если кто-то знает один, отправьте его здесь. Все-таки это было мое решение:

Я создал пользовательский 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 года).

Ответ 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;

Преимущество вышеприведенного кода заключается в том, что он обрабатывает как сериализацию, так и десериализацию и, таким образом, обеспечивает двухстороннюю передачу дат/времени.

Примечание. IsoDateTimeConverter класс является частью библиотеки JSON.NET.

Ответ 3

Сериализовать и десериализовать метод. Зарегистрируйте это как адаптер для GSON

JsonSerializer<Date> ser = new JsonSerializer<Date>() {
@Override
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext 
         context) {
return src == null ? null : new JsonPrimitive(src.getTime());
}
};

JsonDeserializer<Date> deser = new JsonDeserializer<Date>() {
 @Override
 public Date deserialize(JsonElement json, Type typeOfT,
   JsonDeserializationContext context) throws JsonParseException {
return json == null ? null : new Date(json.getAsLong());
 }
 };

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

Ответ 4

Это решение работает для меня с помощью SqlDateTypeAdapter:

SqlDateTypeAdapter sqlAdapter = new SqlDateTypeAdapter();
Gson gson = new GsonBuilder()
   .registerTypeAdapter(java.sql.Date.class, sqlAdapter)
   .setDateFormat("yyyy-MM-dd")
   .create();

Ссылка: fooobar.com/info/483334/...