@DateTimeFormat注解在SpringMvc中一般是用在前端传时间格式字符串,然后后端用Date参数类型直接接收的场景。
一般是在SpringMvc的Controller层中参数前加上@RequestParam或者不加注解使用。
@DateTimeFormat一般用在实体类的字段上,或者是在Controller方法中的某个Date类型的参数前直接加。一般使用patten属性,表示接收的时间字符串格式。
例子1(注:以下例子使用的Content-type都是x-www-form-urlencoded方式):
@RequestMapping("/test")
public Date mytest(@DateTimeFormat(pattern ="yyyy-MM-dd HH:mm:ss") Date time1,
@RequestParam @DateTimeFormat(pattern ="yyyy-MM-dd HH:mm:ss")Date time2) {
System.out.println(time1);
System.out.println(time2);
return time1;
}
例子2:
User.java (实体类)
public class User {
private Integer id;
private String nickname;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss" )
private Date asktime;
@Override
public String toString() {
return "User{" +
"id=" + id +
", nickname=" + nickname +
", asktime=" + asktime +
'}';
}
//Get和Set省略
}
Controller层方法
@RequestMapping("/test")
public User mytest(User user) {
System.out.println(user.toString());
return user;
}
控制台输出结果:
@RequestMapping("/test")
public Date mytest( Date time1,
Date time2) {
System.out.println(time1);
System.out.println(time2);
return time1;
}
请求:
结果(出错):
出现报错:Failed to convert value of type ‘java.lang.String’ to required type ‘java.util.Date’,表明不能把String转换成Date类型,也就是数据不能绑定,因为转换出错。
Tip: 如果在请求的时候,时间格式和注解中设置的不一样也会出错,因为无法转换。
实体类代码修改
@JsonFromat(pattern = "yyyy-MM-dd HH:mm:ss" )
private Date asktime;
出错:Failed to convert property value of type ‘java.lang.String’ to required type ‘java.util.Date’ for property ‘asktime’,因为这时候走的不是jackson的反序列化,所以设置@JsonFormat注解并没有用。
@JsonFormat注解一般是在前端使用application/json 传递参数的时候生效,这时候在Date类型的字段上使用该注解,也能直接接收时间格式的字符串,并且转换成设置的格式。
一般是在SpringMvc的Controller层中JAVA类参数前加上@RequestBody使用,因为前端使用Content-Type是application/json 方式,所以要用@RequestBody来接收参数解析并且绑定。这时候反序列化用到的是Jackjson的反序列化,所以@JsonFormat注解生效。
@JsonFormat注解一般只用在实体类的字段上。patten的属性表示时间字符串格式,timezone属性表示时区。
正确例子(注:以下例子使用的Content-type都是application/json方式):
实体类 User.java
public class User {
private Integer id;
private String nickname;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" )
private Date asktime;
@Override
public String toString() {
return "User{" +
"id=" + id +
", nickname=" + nickname +
", asktime=" + asktime +
'}';
}
}
Controller层代码:
@RequestMapping("/test")
public User mytest(@RequestBody User user) {
System.out.println(user.toString());
return user;
}
其他不变,User实体类的asktime字段注解改变:
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss" )
private Date asktime;
请求:
结果:
报错:Cannot deserialize value of type java.util.Date
from String “2005-2-5 11:22:33”: 说明这时候没有设置时间格式的反序列化,导致出错。
也只改变User实体中的代码
private Date asktime;
拓展: 在SpringMvc中,返回数据的时候,一般都是对象或者其他Map,List类型的数据,这时候
SpringMvc的HttpMessageConvert会自动转换成Json格式的数据输出,所以这时候JSON的序列化配置会生效,因此@JsonFormat注解依然生效,会再序列化成指定的时间格式字符串。
在Springboot中也可以配置全局统一的时间格式配置,如下配置的时间格式就是yyyy-MM-dd HH:mm:ss(如果不配置会使用默认的yyyy-MM-ddTHH:mm:ss.000Z格式):
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
Tip: 我看网上很多人说这两个的区别是:@JsonFormat用来返回给前端的,@DateTimeFormat用来从前端接收Date的。这是不正确的,@JsonFormat也能从前端接收Date,只不过需要前端传递JSON格式的数据,并且Content-Type需要为application/json,让SpringMvc辨识数据为JSON格式,从而让SpringMvc走jackson的序列化和反序列化。