前后端数据格式转换:日期字符串到时间戳的最佳实践
在开发过程中,前端与后端的数据传输格式可能会有不一致的情况。例如,前端传递的日期通常以字符串形式(如 “2006-9-1”)发送,而后端可能需要将其存储为时间戳(如 Unix 时间戳:1157068800
)。
本文将通过一个具体的场景介绍如何实现日期字符串到时间戳的转换。
注意: 这个方法适用于,传递的数据名称一致,但是数据格式不一致的场景
名称不一致可以尝试使用@JsonProperty("XXXX")
场景描述
背景
一个预约管理系统的后端接口需要接收用户的预约信息。其中,用户的出生日期 birthDate
前端以字符串格式传递(例如:“2006-9-1”),后端需要将其存储为秒级时间戳。
问题
由于 User
对象中的 birthDate
定义为 Long
类型,直接反序列化字符串到时间戳会报错,需要自定义处理逻辑。
解决方案
实现步骤
- 使用
@JsonDeserialize
注解:在User
类中为birthDate
属性定义自定义反序列化器。 - 编写自定义反序列化器:通过
Jackson
提供的JsonDeserializer
实现日期字符串到时间戳的转换。
代码实现
User
类
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Data;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;
@Data
public class User {
private Long id; // 编号
private String name; // 姓名
// 使用 @JsonProperty 注解将前端的 sex 映射到后端的 gender
@JsonProperty("sex")
private Integer gender; // 性别(1男 2女)
// 使用自定义反序列化器将字符串转换为时间戳
@JsonDeserialize(using = DateToTimestampDeserializer.class)
private Long birthDate; // 出生日期(秒)
}
自定义反序列化器 DateToTimestampDeserializer
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;
public class DateToTimestampDeserializer extends JsonDeserializer<Long> {
@Override
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String dateStr = p.getText();
// 定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 转换为 LocalDate
LocalDate localDate = LocalDate.parse(dateStr, formatter);
// 转换为时间戳(秒)
return localDate.atStartOfDay(ZoneId.systemDefault()).toEpochSecond();
}
}
测试接口
在UserController
中编写 save
方法,验证数据是否正确转换:
@RestController
@RequestMapping("/wx/user")
public class UserController {
// 保存用户信息
@PostMapping("/save")
public Object save(@RequestBody User user) {
System.out.println("User: " + user);
// TODO: 保存逻辑
return "Success";
}
}
测试输入与输出
前端输入示例
接口URL:
http://localhost:8080/wx/
请求类型:Post
Content-Type:
multipart/form-data
{
"name": "test用户",
"sex": 1,
"birthDate": "2006-9-1",
}
后端日志输出
User: User(birthDate=1157068800, name=test用户, gender=1)
注意事项
- 日期格式匹配:确保前端传递的日期格式与反序列化器中的格式一致(
yyyy-MM-dd
)。 - 时区处理:使用
ZoneId.systemDefault()
确保时间戳符合服务器的时区设置。 - 字段校验:可以使用框架(如 Hibernate Validator)对前端传入的字段进行校验。
总结
通过自定义反序列化器,我们可以轻松实现前端日期字符串到后端时间戳的转换,避免数据类型不匹配的问题。这种方式对其他类似的格式转换场景同样适用,例如处理前端的时间字符串或复杂的嵌套结构数据。