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)/

Кто-нибудь знает, что происходит?

Ответы на вопрос(4)

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

Ref:https://stackoverflow.com/a/30398307/7308789

 AlexM04 февр. 2018 г., 15:18
Это не будет работать в этом случае, так как OP запрашивает дату, записанную как эпоха, а ваше решение ссылается на дату как yyyy-MM-dd.

Другое решение заключается в использовании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.

N

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();
Решение Вопроса

Вот но мне показалось странным, что нет более легкого пути. Несколько других библиотек 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 года).

 Vlado Pandžić18 мая 2017 г., 12:52
Что, если в моем ответе Json есть несколько форматов дат, где некоторые из них поддерживаются Gson, а некоторые нет. Могу ли я проверить формат в методе десериализации и вызвать реализацию по умолчанию, когда форматирование поддерживается, и в то же время выполнять мою пользовательскую десериализацию, когда формат вызывает исключения?
 GreyBeardedGeek14 окт. 2012 г., 04:26
Это правильный способ сделать это. Учитывая, что Microsoft создала свой собственный формат даты, который никто больше не использует, я не нахожу удивительным, что Gson не поддерживает его «из коробки». Почему они просто не используют ISO-8601 как нормальные люди?
 mtmurdock14 окт. 2012 г., 04:34
Я не уверен, но то, что действительно смутило меня, было то, что я использовал другие библиотеки синтаксического анализа Json (на других платформах, отличных от Microsoft), которые справляются с этим просто отлично. Гсон был первым, кого я нашел, который не справился с этим из коробки.
 maaartinus15 окт. 2012 г., 19:20
@GreyBeardedGeek: Там нетвменяемый ISO-8601 формат даты и времени в формате JSON. В JSON нет формата даты и времени; то, что вы имеете в виду, это просто строка. Я не помню точную причину (и больше не могу ее найти), почему им это нужно и почему они выбрали этот путь, но это было довольно убедительно. Может быть, мы должны спросить, почему нет формата даты и времени в JSON? И нет, я действительно не похож на фаната M $.

Ваш ответ на вопрос