日期格式化时注解@DateTimeFormat无效的问题分析

背景
有时候我们在写接口时,需要把前台传来的日期String类型转为Date类型

这时我们可能会用到@DateTimeFormat注解

在请求数据为非JSON格式时,这个注解是没有问题的,可用的;

但是当请求数据为JSON格式时,问题就出现了

此时如果请求参数没有加@RequestBody注解,那么请求参数不会执行类型转换操作,数据都是默认为空(基本类型比如int = 0, 对象引用比如Date date= null)
此时如果请求参数有加@RequestBody注解,那么请求参数会执行JSON类型转换操作,但是转换会提示异常
所以文章题目中所说的有时无效,指的就是上面这两种情况

目录
本文分三步走,如下所示,其中会穿插着介绍@DateTimeFormat、@RequestBody、@JsonFormat注解

 

分析
1. 基础代码:
AnnationApplication.java:主程序兼控制器

package com.jalon.annation;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class AnnationApplication {

public static void main(String[] args) {
SpringApplication.run(AnnationApplication.class, args);
}

@PostMapping("/personPost")
public Person personPost(Person person){
System.out.println(person);
return person;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Person.java 实体类

package com.jalon.annation;

import com.fasterxml.jackson.annotation.JacksonAnnotation;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;

import java.util.Date;

public class Person {

private int age;

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

@Override
public String toString() {
return "Person{" +
"age=" + age +
", birth=" + birth +
'}';
}
// 省略getter/setter
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2. 案例分析:
这里我们用的是PostMan进行测试,请求示例如下

所有示例全程都有@DateTimeFormat注解

示例1:

请求方式:Post请求

数据格式:非JSON格式,比如form-data

请求资源:personPost(Person person),无@RequestBody注解

具体请求内容和返回结果如下所示

 

可以看到,前台返回正常(数据无误),说明@DateTimeFormat有效,成功解析了日期字符串

这里返回的数据都是经过@ResponseBody处理过的,因为我们没有配置返回数据的日期格式化,所以这里返回的日期格式是默认的

@ResponseBody对应于@RequestBody;

前者负责将Java对象序列号成JSON数据进行返回
后者负责解析请求过来的JSON数据,解析成对应的Java对象
我们再来看下后台,打印如下:

Person{age=1, birth=Wed Jan 01 00:00:00 CST 2020}
1
可以看到,后台打印正常(数据无误,日期格式忽略,因为这里的date.toString用的Date的默认方法)

从上面的结果我们可以看到,@DateTimeFormat只是负责解析传来的日期字符串,转为对应的日期对象;

但是并不会修改原有的日期对象的格式(从前台返回和后台输出可以看到,日期格式不受@DateTimeFormat的影响)

示例2:

请求方式:Post请求

数据格式:JSON格式,比如application/json

请求资源:personPost(Person person),无@RequestBody注解

具体请求内容和返回结果如下所示

 

可以看到,返回数据都为空(默认的初始值),说明数据都没有传过去,不止是date,连基本类型int都没过去

我们再来看下后台,打印如下

Person{age=0, birth=null} // 跟前台返回的数据一致
1
可以看到,后台解析到的数据也是空的,所以上面返回的当然是空的

原因就是默认的类型转换器是没有转化成JSON格式的对应转换类的,部分转换器如下所示,(core.convert.support包)



原文链接:https://blog.csdn.net/Jalon2015/article/details/116887302

posted @ 2022-06-02 14:55  stdxxd  阅读(756)  评论(0)    收藏  举报