使用Springboot框架搭建項目
@DateTimeFormat作用是前後到後臺的時間格式的轉換,使用"yyyy-MM-dd"格式的字符串傳入日期類型數據是入參轉換沒有問題,使用"yyyy-MM-dd HH:mm:ss"格式時間字符串就會報錯
@Data
public class DemoVO {
private Date inputTime;
}
報錯信息:
"message": "Could not read document: Can not deserialize value of type java.util.Date from String \"2016-03-03 12:12:12\": not a valid representation (error: Failed to parse Date value '2016-03-03 12:12:12': Can not parse date \"2016-03-03 12:12:12Z\": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSS'Z'', parsing fails (leniency? null))\n at [Source: java.io.PushbackInputStream@541af790; line: 3, column: 14] (through reference chain: com.icbc.patrol.entity.vo.DemoVO[\"inputTime\"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.util.Date from String \"2016-03-03 12:12:12\": not a valid representation (error: Failed to parse Date value '2016-03-03 12:12:12': Can not parse date \"2016-03-03 12:12:12Z\": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSS'Z'', parsing fails (leniency? null))\n at [Source: java.io.PushbackInputStream@541af790; line: 3, column: 14] (through reference chain: com.icbc.patrol.entity.vo.DemoVO[\"inputTime\"])",
原因是springboot默認採用jackson,而jackson只能識別以下幾種日期格式
"yyyy-MM-dd'T'HH:mm:ss.SSSZ";
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
"yyyy-MM-dd";
"EEE, dd MMM yyyy HH:mm:ss zzz";
long類型的時間戳(毫秒時間戳)
解決辦法有以下幾種:
1.、採用long時間戳,如:1537191968000
2、在傳參的對象上加上@JsonFormat註解並且指定時區
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
如果項目中使用json解析框架爲fastjson框架,在實體字段上使用@JsonFormat註解格式化日期
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
3、採用全局處理方式統一處理,推薦這個做法,重寫springboot默認轉換
參考https://blog.csdn.net/qq906627950/article/details/79503801
public class MyDateFormat extends DateFormat {
private DateFormat dateFormat;
private SimpleDateFormat format1 = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
public MyDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
}
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
return dateFormat.format(date, toAppendTo, fieldPosition);
}
@Override
public Date parse(String source, ParsePosition pos) {
Date date = null;
try {
date = format1.parse(source, pos);
} catch (Exception e) {
date = dateFormat.parse(source, pos);
}
return date;
}
// 主要還是裝飾這個方法
@Override
public Date parse(String source) throws ParseException {
Date date = null;
try {
// 先按我的規則來
date = format1.parse(source);
} catch (Exception e) {
// 不行,那就按原先的規則吧
date = dateFormat.parse(source);
}
return date;
}
// 這裏裝飾clone方法的原因是因爲clone方法在jackson中也有用到
@Override
public Object clone() {
Object format = dateFormat.clone();
return new MyDateFormat((DateFormat) format);
}
}
@Configuration
public class WebConfig {
@Autowired
private Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder;
@Bean
public MappingJackson2HttpMessageConverter MappingJsonpHttpMessageConverter() {
ObjectMapper mapper = jackson2ObjectMapperBuilder.build();
// ObjectMapper爲了保障線程安全性,裏面的配置類都是一個不可變的對象
// 所以這裏的setDateFormat的內部原理其實是創建了一個新的配置類
DateFormat dateFormat = mapper.getDateFormat();
mapper.setDateFormat(new MyDateFormat(dateFormat));
MappingJackson2HttpMessageConverter mappingJsonpHttpMessageConverter = new MappingJackson2HttpMessageConverter(
mapper);
return mappingJsonpHttpMessageConverter;
}
}