【问题标题】:com.google.gson.JsonSyntaxException when trying to parse Date/Time in jsoncom.google.gson.JsonSyntaxException 尝试解析 json 中的日期/时间
【发布时间】:2014-05-15 11:57:48
【问题描述】:

我正在使用 RestTemplete 从 rest api 获取 json 数据,我正在使用 Gson 将数据从 json 格式解析为 Object

Gson gson = new Gson();

restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new GsonHttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());

List<Appel> resultList = null;

resultList = Arrays.asList(restTemplate.getForObject(urlService, Appel[].class));

但是我遇到了这个日期问题,我该怎么办..

Could not read JSON: 1382828400000; nested exception is com.google.gson.JsonSyntaxException: 1382828400000

我的 Pojo 体内包含其他 pojos

public class Appel implements Serializable {

    private Integer numOrdre;
    private String reference;
    private String objet;
    private String organisme;
    private Double budget;
    private Double caution;
    private Date dateParution;
    private Date heureParution;
    private Date dateLimite;
    private Date heureLimite;
    private List<Support> supportList;
    private Ville villeid;
    private Categorie categorieid;

    public Appel() {
    }

    public Appel(Integer numOrdre, String reference, String objet, String organisme, Date dateParution, Date heureParution, Date dateLimite) {
        this.numOrdre = numOrdre;
        this.reference = reference;
        this.objet = objet;
        this.organisme = organisme;
        this.dateParution = dateParution;
        this.heureParution = heureParution;
        this.dateLimite = dateLimite;
    }

这是我的 API 返回的 json

[
   {
       "numOrdre": 918272,
       "reference": "some text",
       "objet": "some text",
       "organisme": "some text",
       "budget": 3000000,
       "caution": 3000000,
       "dateParution": 1382828400000,
       "heureParution": 59400000,
       "dateLimite": 1389657600000,
       "heureLimite": 34200000,
       "supportList":
       [
           {
               "id": 1,
               "nom": "some text",
               "dateSupport": 1384732800000,
               "pgCol": "013/01"
           },
           {
               "id": 2,
               "nom": "some text",
               "dateSupport": 1380236400000,
               "pgCol": "011/01"
           }
       ],
       "villeid":
       {
           "id": 2,
           "nom": "Ville",
           "paysid":
           {
               "id": 1,
               "nom": "Pays"
           }
       },
       "categorieid":
       {
           "id": 1,
           "description": "some text"
       }
   },
  .....
]

【问题讨论】:

  • 你的 json 是什么样的?你的pojo是什么样的?
  • 您正试图投射一个长日期。
  • 这些值,1384732800000,看起来像时间戳。 Gson 未设置为解析带有时间戳的日期。您必须使用自定义 TypeAdapter 对其进行配置。
  • 您需要使用 GsonBuilder 并传递日期格式化程序字符串,以便 Gson 知道如何解析您的日期。这是一个示例:stackoverflow.com/a/34187419/1103584

标签: java android json gson


【解决方案1】:

1382828400000 值很长(以毫秒为单位)。您告诉GSON,该字段是Date,它不能自动将long 转换为Date

您必须将字段指定为长值

private long dateParution;
private long heureParution;
private long dateLimite;
private long heureLimite;

GSON 将 JSON 字符串转换为所需的 Appel 类实例之后,构造另一个对象,将这些字段作为日期,并在将值分配给新对象的同时对其进行转换。

另一种选择是实现您自己的自定义反序列化器:

 public class CustomDateDeserializer extends DateDeserializer {
     @Override
     public Date deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
         // get the value from the JSON
         long timeInMilliseconds = Long.parseLong(jsonParser.getText());

         Calendar calendar = Calendar.getInstance();
         calendar.setTimeInMillis(timeInMilliseconds);
         return calendar.getTime();
     }
 }

你必须在你想要的字段上设置这个自定义反序列化器,在 setter 方法上,比如:

@JsonDeserialize(using=CustomDateDeserializer.class)
public void setDateParution(Date dateParution) {
    this.dateParution = dateParution;
}

【讨论】:

    【解决方案2】:

    我最终要做的是进入我的 API 项目并创建一个 CustomSerializer

    public class CustomDateSerializer extends JsonSerializer<Date> {  
    
        @Override
        public void serialize(Date t, JsonGenerator jg, SerializerProvider sp) throws IOException, JsonProcessingException {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String formattedDate = formatter.format(t);
    
            jg.writeString(formattedDate);
        }
    }
    

    返回格式 yyyy-MM-dd 并且我用注释日期字段

    @JsonSerialize(using = CustomDateSerializer.class)
    

    在我的 Android 应用程序中,我将 Gson 对象创建为

                Reader reader = new InputStreamReader(content);
    
                GsonBuilder gsonBuilder = new GsonBuilder();
                gsonBuilder.setDateFormat("yyyy-MM-dd");
                Gson gson = gsonBuilder.create();
                appels = Arrays.asList(gson.fromJson(reader, Appel[].class));
                content.close();
    

    它现在可以工作了。谢谢你的帮助我很感激

    【讨论】:

    【解决方案3】:

    不再需要自定义序列化程序 - 只需使用 GsonBuilder,并指定日期格式,如下所示:

    Timestamp t = new Timestamp(System.currentTimeMillis());
    
    String json = new GsonBuilder()
                   .setDateFormat("yyyy-MM-dd hh:mm:ss.S")
                   .create()
                   .toJson(t);
    
    System.out.println(json);
    

    【讨论】:

      猜你喜欢
      • 2020-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 2019-11-26
      • 1970-01-01
      相关资源
      最近更新 更多