【问题标题】:JSON Serializing date in a custom format (Can not construct instance of java.util.Date from String value)JSON 以自定义格式序列化日期(无法从字符串值构造 java.util.Date 的实例)
【发布时间】:2013-07-13 09:27:01
【问题描述】:
could not read JSON: Can not construct instance of java.util.Date from String 
value '2012-07-21 12:11:12': not a valid representation("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))

将 json 请求传递给 POJO 类中的 REST 控制器方法。用户应仅以低于日期时间格式输入,否则应抛出消息。为什么 DateSerializer 不调用?

add(@Valid @RequestBody User user)
{
}

json:

{
   "name":"ssss",
   "created_date": "2012-07-21 12:11:12"
}

pojo 类变量

@JsonSerialize(using=DateSerializer.class)
@Column
@NotNull(message="Please enter a date")      
@Temporal(value=TemporalType.TIMESTAMP)
private Date created_date;

public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
    logger.info("serialize:"+value);
    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    logger.info("DateSerializer formatter:"+formatter.format(value));
    jgen.writeString(formatter.format(value));
}

【问题讨论】:

    标签: json spring-mvc jackson fasterxml


    【解决方案1】:
    1. 如果要将JSON 字符串绑定到日期,则此过程称为deserialization,而不是serialization
    2. 要将JSON 字符串绑定到日期,请创建自定义日期反序列化,注释created_date 或其设置器

      @JsonDeserialize(using=YourCustomDateDeserializer.class)

    你必须在哪里实现 public Date deserialize(...) 方法来告诉 Jackson 如何将字符串转换为日期。

    享受吧。

    【讨论】:

      【解决方案2】:

      我有同样的问题,所以我写了一个自定义日期反序列化 @JsonDeserialize(using=CustomerDateAndTimeDeserialize.class)

      public class CustomerDateAndTimeDeserialize extends JsonDeserializer<Date> {
      
          private SimpleDateFormat dateFormat = new SimpleDateFormat(
                  "yyyy-MM-dd HH:mm:ss");
      
          @Override
          public Date deserialize(JsonParser paramJsonParser,
                  DeserializationContext paramDeserializationContext)
                  throws IOException, JsonProcessingException {
              String str = paramJsonParser.getText().trim();
              try {
                  return dateFormat.parse(str);
              } catch (ParseException e) {
                  // Handle exception here
              }
              return paramDeserializationContext.parseDate(str);
          }
      }
      

      【讨论】:

      • 你是如何实现这个 CustomerDateAndTimeDeserialize 类的?
      【解决方案3】:

      使用JsonFormat 注释注释您的created_date 字段以指定输出格式。

      @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = TimeZone.getDefault(), locale = Locale.getDefault())
      

      请注意,您可能需要传入不同的 Locale 和 TimeZone,如果它们应该基于服务器使用之外的其他内容。

      您可以在the docs 中找到更多信息。

      【讨论】:

      • 您只需要这样做吗?我试过这个,它本身不起作用。也许某处需要其他一些注释?
      • 注意使用这个注解。这是已知的issue,还有一天的时间。
      • 如果你想要一个正确的时间,不要忘记在“模式”之后添加 timezone =“Canonical_ID_of_your_timezone”参数。时区名称可以在这里找到:joda-time.sourceforge.net/timezones.html
      • 或者使用:@Pattern(regexp = Constants.REGEX)
      【解决方案4】:

      另一种方法是使用一个自定义的 Date 对象来处理自己的序列化。

      虽然我并不认为扩展像DateLong 等简单对象是一个好习惯,但在这种特殊情况下,它使代码易于阅读,在定义格式和与普通的Date 对象兼容。

      public class CustomFormatDate extends Date {
      
          private DateFormat myDateFormat = ...; // your date format
      
          public CustomFormatDate() {
              super();
          }
      
          public CustomFormatDate(long date) {
              super(date);
          }
      
          public CustomFormatDate(Date date) {
              super(date.getTime());
          }
      
      
          @JsonCreator
          public static CustomFormatDate forValue(String value) {
              try {
                  return new CustomFormatDate(myDateFormat.parse(value));
              } catch (ParseException e) {
                  return null;
              }
          }
      
          @JsonValue
          public String toValue() {
              return myDateFormat.format(this);
          }
      
          @Override
          public String toString() {
              return toValue();
          }
      }
      

      【讨论】:

        【解决方案5】:

        我通过以下步骤解决了这个问题。

        1.在实体类中使用@JsonDeserialize对其进行注释

        @Entity
        @Table(name="table")
        public class Table implements Serializable {
        // Some code
        @JsonDeserialize(using= CustomerDateAndTimeDeserialize.class)
        @Temporal(TemporalType.TIMESTAMP)
        @Column(name="created_ts")
        private Date createdTs
        }
        
        1. 写 CustomDateAndTimeDeserialize.java Sample Code

        【讨论】:

          【解决方案6】:

          对于某人,如果您使用 DTO/VO/POJO 来映射您的请求,您可以简单地注释您的日期字段

          @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
          private Date customerRegDate;
          

          而json请求应该是:

          {
          "someDate":"2020-04-04 16:11:02"
          }
          

          您不需要注释实体类变量。

          【讨论】:

          • 日期为空怎么办?
          【解决方案7】:

          我需要使用@JsonFormat 进行注释,然后,这运行良好:

          @Temporal(TemporalType.DATE)
          @DateTimeFormat(pattern = "MM-dd-yyyy")
          @JsonFormat(pattern = "MM-dd-yyyy")
          private java.util.Date expDate;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-08-09
            • 2019-06-14
            • 1970-01-01
            • 2018-02-02
            • 2020-02-12
            • 1970-01-01
            相关资源
            最近更新 更多