原文网址:SpringBoot--LocalDateTime格式转换(响应给前端)_IT利刃出鞘的博客-CSDN博客
简介
说明
项目我们经常会有前后端时间转换的场景,比如:创建时间、更新时间等。一般情况下,前后端使用时间戳或者年月日的格式进行传递。
如果后端收到了前端的参数每次都手动转化为想要的格式,后端每次将数据传给前端时都手动处理为想要的格式实在是太麻烦了。
基于如上原因,本文用示例介绍SpringBoot全局格式配置,将LocalDateTime自动转化为想要的格式传给前端。
相关网址
SpringBoot--LocalDateTime格式转换(前端入参)_IT利刃出鞘的博客-CSDN博客
备注
有人说,可以这样配置:
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-dates-as-timestamps: false
- 这种配置只适用于Date这种,不适用于LocalDateTime等。
- LocalDateTime序列化/反序列化时默认格式为:"2020-08-19T16:30:18.823"。
时间戳格式
方案1:自定义序列化器(局部)
简介
本法只能用于将数据转为时间戳响应给前端,无法自动解析前端传进来的时间戳(无论是直接接收还是通过实体类接收都不行)。
此方法不仅仅可以用于返给前端数据,也可以用于后端的转换:使用jackson的ObjectMapper().writeValueAsString方法将对象转为json字符串。而下边的全局配置就不可以。
配置类
package com.example.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
public class LocalDateTimeConfig {
// 序列化实现
public static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
if (value != null) {
long timestamp = value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
gen.writeNumber(timestamp);
}
}
}
// 反序列化实现
public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext)
throws IOException {
long timestamp = p.getValueAsLong();
if (timestamp > 0) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
} else {
return null;
}
}
}
}
Entity
package com.example.business.entity;
import com.example.config.LocalDateTimeConfig;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
public class User {
private Long id;
private String userName;
@JsonSerialize(using = LocalDateTimeConfig.LocalDateTimeSerializer.class)
private LocalDateTime createTime;
}
Controller
package com.example.business.controller;
import com.example.business.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("getUser")
public User getUser() {
return new User(null, "Tony", LocalDateTime.now());
}
}
测试
postman访问:http://localhost:8080/user/getUser
postman结果:
注意:本法只能用于将数据转为时间吹响应给前端,无法自动解析前端传进来的时间戳。示例如下:
代码
package com.example.business.entity;
import com.example.config.LocalDateTimeConfig;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
public class User {
private Long id;
private String userName;
@JsonSerialize(using = LocalDateTimeConfig.LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeConfig.LocalDateTimeDeserializer.class)
private LocalDateTime createTime;
}
package com.example.business.controller;
import com.example.business.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
@RestController
@RequestMapping("user")
public class UserController {
@PostMapping("save")
public User save(User user) {
System.out.println("保存用户:" + user);
return user;
}
}
测试
postman访问:http://localhost:8080/user/save?userName=Tony&createTime=1631790000
postman结果:
后端结果:
2021-09-16 19:41:26.855 WARN 93488 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'user' on field 'createTime': rejected value [1631790000]; codes [typeMismatch.user.createTime,typeMismatch.createTime,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.createTime,createTime]; arguments []; default message [createTime]]; default message [Failed to convert value of type 'java.lang.String[]' to required type 'java.time.LocalDateTime'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@com.fasterxml.jackson.databind.annotation.JsonSerialize @com.fasterxml.jackson.databind.annotation.JsonDeserialize java.time.LocalDateTime] for value '1631790000'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [1631790000]]]
方案2:配置ObjectMapper(全局)
上边是本文的部分内容,为便于维护,全文已转移到此网址:SpringBoot–全局处理LocalDateTime响应格式(时间戳) - 自学精灵