文章目录

一、场景复现
1. 准备实体vo

定义⼀个pojo,它有⼀个 java.util.Date 类型的属性 createDate。

package com.sinosoft.business.request;

import lombok.Data;

import java.util.Date;

/**
* String类型日期接收处理类
*
* @Author gblfy
* @Date 2022-05-26 22:05
**/
@Data
public class DateReq {
/**
* 创建时间
*/
private Date createDate;
}
2. 定义⼀个Controller
package com.sinosoft.business.controller;

import com.sinosoft.business.request.DateReq;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
* TODO
*
* @Author gblfy
* @Date 2022-05-26 22:12
**/
@RestController
@RequestMapping("/date/")
public class DateController {

@RequestMapping("test")
public DateReq getDate(DateReq vo){
System.out.println("date1:"+vo.getCreateDate());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = sdf.format(vo.getCreateDate());
System.out.println("date2:"+date);
DateReq vo2 = new DateReq();
vo2.setCreateDate(new Date());

return vo2;
}
}
3. 请求测试

访问 /date/test ,并传⼊参数:2022-05-26 20:13:21

发现并不能访问成功,会抛出异常:

@DateTimeFormat和@JsonFormat注解_java

分析->因为传⼊的参数是 String 类型的,⽽⽤来接收参数的 DateReq 的 date 属性是 java.util.Date 类型的,类型⽆法转换。

二、⼊参格式化

这时,就可以使⽤ Spring 的 @DateTimeFormat 注解格式化参数,来解决上述问题。
改造 DateReq:

2.1. 日期转换
@Data
public class DateReq {
/**
* 创建时间
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createDate;
}
2.2. 请求测试

再像上⾯⼀样访问​​http://localhost:8080/date/test?createDate=2022-05-26 20:13:21​​,并传⼊参数:2022-05-26 20:13:21

@DateTimeFormat和@JsonFormat注解_json_02

返回参数变成了数字,等会解决

将在控制台上打印:

date1:Thu May 26 20:13:21 CST 2022

date2:2022-05-26 20:13:21

@DateTimeFormat和@JsonFormat注解_日期格式化_03

可以看到,加⼊ @DateTimeFormat 注解后参数可以被接收到了,但⽇期时间的格式还是需要⾃⼰再⼿动转换⼀下。
因为 @DateTimeFormat 注解的 pattern 属性值指定的⽇期时间格式并不是将要转换成的⽇期格式,这个指定的格式是和传⼊的参数对应
的。
假如注解为:
@DateTimeFormat(pattern=“yyyy/MM/dd HH:mm:ss”)
则传⼊的参数应该是这样的:
2022/05/26 20:13:21
否则会抛出异常。

三、 出参格式化
3.1. 现象

在上述⽰例中,调⽤接⼝的返回结果为:
“date”: “Thu May 26 20:13:21 CST 2022”

3.2. 改造

这个格式并不是我们想要的,那么如何将其进⾏格式化?这时就需要⽤到 jackson 的 @JsonFormat 注解。
改造 DateReq:

@Data
public class DateReq {
/**
* 创建时间
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
}
3.4. 测试验证

继续访问 /date/test ,并传⼊参数:2022-05-26 20:13:21,可以看到接⼝返回的结果为:
“date”: “2022-05-26 20:13:21”

3.5. 时间少了8小时

虽然时间格式正确了,但实际上当前时间是 “2022-05-26 12:13:21” ,早了8个⼩时。因为,jackson在序列化时间时是按照国际标准
时间GMT进⾏格式化的,⽽在国内默认时区使⽤的是CST时区,两者相差8⼩时。
所以,@JsonFormat 注解还要再加⼀个属性:

3.6. 解决方案
  • 1 添加注解属性
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createDate;
  • 2 添加时区
    数据库连接添加
&serverTimezone=Asia/Shanghai

这样,结果就正确了。

因为 @JsonFormat 注解不是 Spring ⾃带的注解,所以使⽤该注解前需要添加 jackson 相关的依赖包。当然,如果是 SpringBoot 项⽬

就不需要⾃⼰⼿动添加依赖了,因为在 spring-boot-start-web 下已经包含了 jackson 相关依赖

@DateTimeFormat和@JsonFormat注解_java_04

3.7. 效果图

@DateTimeFormat和@JsonFormat注解_json_05