JSON 以自定义格式序列化日期(无法从字符串值构造 java.util.Date 的实例)
Posted
技术标签:
【中文标题】JSON 以自定义格式序列化日期(无法从字符串值构造 java.util.Date 的实例)【英文标题】:JSON Serializing date in a custom format (Can not construct instance of java.util.Date from String value) 【发布时间】: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));
【问题讨论】:
【参考方案1】:-
如果要将
JSON
字符串绑定到日期,则此过程称为deserialization
,而不是serialization
。
要将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 中找到更多信息。
【讨论】:
您只需要这样做吗?我试过这个,它本身不起作用。也许某处需要其他一些注释? 你需要使用杰克逊:fasterxml.github.io/jackson-annotations/javadoc/2.0.0/com/… 注意使用这个注解。这是已知的issue,还有一天的时间。 如果你想要一个正确的时间,不要忘记在“模式”之后添加 timezone =“Canonical_ID_of_your_timezone”参数。时区名称可以在这里找到:joda-time.sourceforge.net/timezones.html 或者使用:@Pattern(regexp = Constants.REGEX)【参考方案4】:另一种方法是使用一个自定义的 Date 对象来处理自己的序列化。
虽然我并不认为扩展像Date
、Long
等简单对象是一个好习惯,但在这种特殊情况下,它使代码易于阅读,在定义格式和与普通的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
-
写 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;
【讨论】:
以上是关于JSON 以自定义格式序列化日期(无法从字符串值构造 java.util.Date 的实例)的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot中使用@RequestBody时如何自定义需要转换的日期格式