前端时间控件,一般情况下直接会传一个yyyy-MM-dd的日期字符串到后台。这个时候如果我们直接用java.util.Date类型就无法正确接收到。或者我们从数据库里查到DateTime类型并且用java的Date类型接收并返回给前台的时候,前台也无法用yyyy-MM-dd的形式进行呈现。
这个时候,前面两种情况分别对应了@DateTimeFormat和@JsonFormat注解的使用。
该注解主要解决前端时间控件传值到后台接收准确的Date类属性的问题,我们可以在需要接收的类中对应的时间类型属性上加上@DateTimeFormat注解,并在注解中加上pattern属性,例如:
/**
* @author liu
* @date 2022年04月14日 16:31
*/
@Data
public class User {
private String createTime;
private String orderTime;
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
//@DateFormatValidation(format = "yyyy-MM-dd HH:mm:ss", message = "与要求的日期格式[yyyy-MM-dd HH:mm:ss]不符")
private LocalDateTime genTime;
}
同样,我们在对应的接收对象时间类型上加上@JsonFormat注解,并在注解中加上pattern属性以及timezone属性
例如
/**
* @author liu
* @date 2022年04月14日 16:31
*/
@Data
public class User {
private String createTime;
private String orderTime;
// @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
//@DateFormatValidation(format = "yyyy-MM-dd HH:mm:ss", message = "与要求的日期格式[yyyy-MM-dd HH:mm:ss]不符")
private LocalDateTime genTime;
}
@DateTimeFormat只会在类似@RequestParam的请求参数(url拼接的参数才生效)上生效,如果@DateTimeFormat放到@RequestBody下是无效的。
在@RequestBody中则可以使用@JsonFormat把传给后台的时间字符串转成Date,也就是说**@JsonFormat其实既可以把传给后台的时间字符串转成Date也可以把后台传出的Date转成时间字符串**。
代码
/**
* @author liu
* @date 2022年04月14日 16:31
*/
@Data
public class User {
private String createTime;
private String orderTime;
// @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
//@DateFormatValidation(format = "yyyy-MM-dd HH:mm:ss", message = "与要求的日期格式[yyyy-MM-dd HH:mm:ss]不符")
private LocalDateTime genTime;
}
传输对象
/**
* @author liu
* @date 2022年04月26日 10:42
*/
@Data
public class UserSaveDto {
private String code;
private List list ;
}
/**
* @author liu
* @date 2022年04月26日 10:42
*/
@RestController
@RequestMapping("task")
public class TestController {
@PostMapping(value = "/addTasks")
public String addTasks(@RequestBody UserSaveDto userSaveDto) {
String code = userSaveDto.getCode();
List list = userSaveDto.getList();
System.out.println(code);
return list.toString();
}
@GetMapping(value = "/getTasks")
public String getTasks() {
return "qqiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";
}
public static void main(String[] args) {
UserSaveDto userSaveDto = new UserSaveDto();
userSaveDto.setCode("qq");
ArrayList list = new ArrayList();
User user = new User();
user.setCreateTime("aa");
user.setOrderTime("xx");
user.setGenTime(LocalDateTime.now());
list.add(user);
userSaveDto.setCode("11");
userSaveDto.setList(list);
String json = JsonUtils.getJson(userSaveDto, "yyyy-MM-dd HH:mm:ss");
System.out.println(json);
}
}
用apiPost测试时
测试字符串{
“code”: “11”,
“list”: [
{
“createTime”: “aa”,
“orderTime”: “xx”,
“genTime”: “2022-04-26 15:17:59”
}
]
}
看似没有问题但后台一直报错
2022-04-26 15:50:22.423 WARN 39112 — [nio-9090-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type java.time.LocalDateTime
from String “2022-04-26 15:17:59”: Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text ‘2022-04-26 15:17:59’ could not be parsed at index 11; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.time.LocalDateTime
from String “2022-04-26 15:17:59”: Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text ‘2022-04-26 15:17:59’ could not be parsed at index 11 at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 68] (through reference chain: com.example.demo.test.UserSaveDto[“list”]->java.util.ArrayList[0]->com.example.demo.test.User[“genTime”])]
时间格式还是不准确,可能我们考虑是不是注解不好用,错了,是你的json字符串有问题
必须是json格式化出来的字符串
json工具类
package com.example.demo.test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.text.SimpleDateFormat;
/**
* @author liu
* @date 2022年04月26日 15:02
*/
public class JsonUtils {
/**
* 功能描述: 重载方法,只传入一个object就可以,默认的日期格式就是"yyyy-MM-dd HH:mm:ss"
* @return java.lang.String
*/
public static String getJson(Object object) {
return getJson(object, "yyyy-MM-dd HH:mm:ss");
}
//静态方法,拿来即用,日期就输入格式,不是日期就调用上面的,就日期格式也不影响
public static String getJson(Object object, String dateformat) {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.registerModule(new JavaTimeModule());
//不使用时间差的方式 WRITE_DATE_KEYS_AS_TIMESTAMPS:将日期键作为时间戳写入 改为false
mapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
SimpleDateFormat format = new SimpleDateFormat(dateformat);
//指定日期格式
mapper.setDateFormat(format);
try {
//就是不是日期对象也不影响,都是正常调用了writeValueAsString方法
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//如果有异常,就返回null
return null;
}
}
格式化出来的字符串
{
“code”: “11”,
“list”: [
{
“createTime”: “aa”,
“orderTime”: “xx”,
“genTime”: “2022-04-26 15:17:59”
}
]
}
然后再发请求
响应
[User(createTime=aa, orderTime=xx, genTime=2022-04-26T15:17:59)]
OK