关于Javascript Date向后端Java传参的问题
个人水平有限,欢迎指正,谢谢
目前最常见的做法(不推荐的做法)
后端java实体属性增加Spring注解,设置格式,在传参过程中,Spring自动将JavaScript字符串例如 "2019-01-17 16:00:00" 转化为Java的Date类型
- Java实体属性增加注释
public Class MyDemo {
// 注解接收日期字符串参数,后端不是很熟,可能不是这个注解,欢迎指正
@DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”)
private Date date;
public void setDate (Date date) {
this.date = date;
}
public Date getDate () {
return this.date;
}
}
- 前端向后端传参时,将Date类型的数据格式化成字符串
// 假使存在格式化日期的方法
import dateFormat from './xxx'
// 将日期转换成特定字符串
let dateString = dateFormat(new Date()) // => "2019-01-17 16:00:00"
// 后端在Controller接口中直接使用 MyDemo 接收参数,则前端传递的字符串会进过Spring直接转换为Java Date类型数据
// 例如jQuery发送请求
$.post('/xxx/xxx', {
date: dateString
}).done((result = {}) => {
console.log(result)
})
此时浏览器控制台传参应该是这个样子的

分析这种传参方式的弊端
- 后端需要引入Spring注解,每个Date类型的属性都要增加注解(增加工作量)
- 前端需要将日期转换成字符串,每个向后端传递的日期都要调用格式化函数格式化(当然也是增加工作量)
- 这个比较严重的问题,浏览器new Date()创建的实例有时区信息,而转换成字符串之后丢失了时区信息,后端在转换数据的时候,只能将字符串装换成【服务器所在时区的时间】 ,假如客户端在美国,服务器在中国,那么传递数据之后,后端会将美国当地时间 "2019-01-17 16:00:00" 转换成中国北京时间然后保存到数据库中,而当用户再浏览这条数据的时候,通常后端传递给前端的是时间戳,此时浏览器 new Date(time) 会自动将时间传唤为当地时间来展示,此时用户看到的数据和自己保存时的时间是完全不相同的。例如:旧金山和北京相差了16小时(北京东八区、旧金山夏令时西八区),保存时: 西八区 "2019-01-17 16:00:00" 被保存为 东八区 "2019-01-17 16:00:00",而数据展示时:东八区 "2019-01-17 16:00:00" 会自动被转换成 西八区 "2019-01-17 00:00:00",显然这个不是用户想要的结果。
推荐做法
曾经看过关于JavaScript语言设计的相关文章(具体忘记了),JavaScript设计语言的时候,Date类型参照了Java的Date类型,其实通过实例的Api也能看出大多数相同的地方,比如获取年、月、日、周几、当月第几天等等。所以实际上JavaScript的Date类型数据可以无阻碍的转换为Java的Date类型。
// 例如jQuery发送请求
$.post('/xxx/xxx', {
date: new Date()
}).done((result = {}) => {
console.log(result)
})
此时浏览器控制台传参应该是这个样子的

分析这种传参方式的好处
- 后端不用给实例加注解,同时前端也不用格式化日期,而且很多前端框架组件都支持Date类型的model。
- 传参时,实际上调用了 new Date().toJSON() 将当地日期转换为标准时区的时间字符串。Java接收参数后自动将时间转换为服务器所在时区时间。
- 展示数据时,服务器所在时区的时间会根据客户端所在的时区进行自动转换,由于转换过程都是参照标准时区,所以不会存在时区误差。