Jackson(2)之@JsonFormat和@DateTimeFormat本质区别

1.问题

平时在开发中前后端交互经常遇到两个问题:

  • 1. 后端给前端返数据时,moudel对象里的Date属性,需要格式化后给前端展现(比如:格式化成yyyy-MM-dd HH:mm:ss)。
  • 2. 前端给后端接口传参数时,格式化的时间字符串(比如:createTime="2020-11-29 20:10:11")需要转化成后端moudel对象里Date属性。

解决这两个问题有两种方式:

  • 1. 手动格式化处理:比如,每次返给前端的数据使用SimpleDateFormat将Date转化成指定格式的字符串,接受参数也一样。这种方式会在只要有Date类型交互的接口处都要手动转化,繁琐、代码冗余。
  • 2. 使用注解:@JsonFormat 和 @DateTimeFormat,两者的使用方式和区别有所不同。

2.@JsonFormat注解 和 @DateTimeFormat的区别

  • (1)@JsonFormat注解是Jackson的注解, Spring MVC和Spring Boot的默认 json解析器便是 Jackson;@DateTimeFormat注解是spring的注解。

  • (2)@DateTimeFormat注解只接收处理 前端form表单post请求里键值对有时间的参数转换;@JsonFormat注解只能处理标准的post请求(Content-type=application/json)里的时间转换。

(1)form表单的键值对请求

表单post请求包含两种:Content-type=application/x-www-form-urlencoded 和 Content-type=multipart/form-data,前端用表单post请求时,接口参数上不需要加@RequestBody注解,参数直接从表单的key/value中获取。

@RestController
public class LearnDataController{
    @PostMapping("/learn/data/get/userInfo")
    public void userInfo(UserInfo userInfo) throws Exception {
        System.out.println(userInfo);
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(userInfo);
        System.out.println(json);
    }
}
@Data
public class UserInfo implements Serializable {
    private Long id;
    private String name;
    private Integer age;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date birthDate;
}

//注意:表单类型的post请求时,后端Controller接口不需要加@RequestBody注解,参数UserInfo里的时间属性只能用@DateTimeFormat来规定接收的时间格式。

(2)标准json格式的post请求

前端发送标准的post请求时(即Content-type=application/json),需要在参数上增加@RequestBody这个注解,说明参数是从http的requestbody中获取的。

@RestController
public class LearnDataController{
    @PostMapping("/learn/data/get/userInfo")
    public void userInfo(@RequestBody UserInfo userInfo) throws Exception {
        System.out.println(userInfo);
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(userInfo);
        System.out.println(json);
    }
}
//标准的post请求时(Content-type=application/json),需要加@RequestBody从body里取参数。参数UserInfo里的时间属性,只能用@JsonFormat来接收指定时间格式的参数。
@Data
public class UserInfo implements Serializable {
    private Long id;
    private String name;
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT + 8")
    private Date birthDate;
}

(3)后端给前端返值

当后端给前端传时间值时,只能用@JsonFormat返回指定格式字符给前端,@DateTimeFormat无法决定返回值的格式。因为spring反序列化默认用的Jackson框架。

3.总结

(1).前端 传给 后端
    当前端传来的是键值对(两种form表单post请求),用@DateTimeFormat 规定接收的时间格式。
    当前端传来json串,后台用@ReuqestBody接收,用@JsonFormat规定接收的时间格式。

(2).后端 传给 前端
    后端返回给前端的时间值,只能用@JsonFormat返回指定格式字符给前端,@DateTimeFormat无法决定返回值的格式。

(3).@JsonFormat 是jackson提供;@DateTimeFormat 由spring提供。

#(1)@DateTimeFormat是spring的注解,目的是解决前端form表单提交的post请求时,规定接收的时间格式。

#(2)form表单post请求有两种,当前端传来的参数有时间类型时,用@DateTimeFormat规定接收的时间格式。
    1)Content-type=application/x-www-form-urlencoded 它是表单默认的提交类型,基于key/value形式提交到服务端的。
    2)Content-type=multipart/form-data 它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。

最后想聊点其它的,今天看了胡润百富榜里的企业家,过千亿的身价背后都是百亿、千亿级的负债。比如前段时间的蚂蚁金服,2万亿的贷款规模,里面有98%是干儿子的;再比如今年的地产谁不是干过了三条红线,基本都是盘子越大,负债越高。感慨呀,像我们这样的普通人,要想实现几代人的阶级跳跃,只有靠不断加杠杆加杠杆才有点可能。很多人这一辈子,也只有买房这一次机会可以得到加杠杆的条件,然而在选择首付和按揭时又失去了这次唯一的机会。

                                                                                                                 

                                                                                                          2020年11月29日  晚  于北京记

你可能感兴趣的:(Jackson,java,json,spring)