
标题太长有木有?主要是为了把问题描述清楚,免得进错文章。
昨天测试的同事测试接口的时候,测试出来一个Date类型校验问题。
要求输入的日期格式是:yyyy-MM-dd HH:mm:ss,Vo中使用的注解如下:
测试同事输入下面两种参数都是保存成功,当输入为“202105”参数时,保存的数据变为“1970-01-01 08:03:22”,由此发现这个问题。
常用的三种日期格式化的注解解释如下:
由于 @RequestBody 注解先将json字符串转换成对应的Vo对象,Vo对象中的字段上添加的注解再生效, @DateTimeFormat 只是做格式化,无法做格式校验。
用自定义注解进行json字符串中的日期格式做校验。
解决思路 :
1从request对象中获取原始json字符串入参 。由于自定义注解接口ConstraintValidator的实现获取到的参数值是@RequestBody注解将json字符串参数解析成Vo对象后的Date对象,不是原始json字符串值,所以需要从request中获取json原始参数值;
2获取到json入参原始值使用正则表达式对日期进行格式进行校验 。
温馨提示 :
1由于自定义注解中是无法直接获取到request对象,所以需要按照各自框架获取request对象的方式进行获取。
2获取到的原始json字符串入参可能包含 空格 、 回车 、 换行符 、 制表符 这些特殊字符,所以需要进行特殊字符处理。
3获取Vo对象中添加注解的属性名。
详细见: getFieldName(ConstraintValidatorContext context)即:((ConstraintValidatorContextImpl) context)basePathcurrentLeafNodename
SearchTaskVojava
DateFormatValidationjava
DateFormatValidatorjava
至此问题解决~
文章中有何隐藏问题欢迎留言交流~
有好的解决方案欢迎留言~
1341417600000 是自格林威治标准时间 1970 年 1月 1 日 0:00:00 后经过的时间,以毫秒为单位。0800是时区。
我给你个用毫秒数和时区设置日期的例子。
import javautilCalendar;
import javautilDate;
import javautilTimeZone;
public class L {
public static void main(String[] args) {
long l=1341417600000l;
TimeZone zone=TimeZonegetTimeZone("GMT+0800");
Calendar c=CalendargetInstance(zone);
csetTimeInMillis(l);
Date d=cgetTime();
Systemoutprintln(d);
Systemoutprintln(zone);
}
}
运行结果:
Thu Jul 05 00:00:00 CST 2012
sunutilcalendarZoneInfo[id="GMT+08:00",offset=28800000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
Java Bean传递过程中Date的格式化过程中时区的处理是一件非常恼人的事情。相信碰到过相关问题的同学应该深有体会。笔者最近也是频频采坑,终于略有收获虽然未能大彻大悟但对付平时开发应该绰绰有余,感兴趣的同学可以持续关注后面进展会持续更新。
首先进入正题前要说明两点,一个是时区的出现只是为了适应不同的地区的本地化时间展示应运而生的他不应该改变绝对的时间,再一个是new Date产生的长整数是一个从 格林威治时间(0时区)1970年1月1日 起的毫秒数的时间戳。换句话说全世界的程序员同时new Date()得到的这个时间戳应该是一致的,这个就是我所谓的一个绝对时间。我们看到的北京时间上午八点也好,伦敦时间凌晨0点也好只是把这个绝对时间换算成当地时间得到的一个展示形式。
JSON的Date传递过程中通常有两种方式一种是直接传递Date的13位长的时间戳,一种是传递格式化后的类似2019-05-06 11:31:13708型的字符串。两种方式各有优劣吧,其中传递格式化后的字符串比较直观但是需要处理时区问题,传递时间戳不太直观但是不需要处理时区问题。
假如要传递格式化后的字符串通常需要在序列化的属性上加上@JsonFormat(timezone ="UTC", pattern ="yyyy-MM-dd HH:mm:ssS")的注解,在序列化过程中表示需要将date 格式化为UTC时区的yyyy-MM-dd HH:mm:ssS形式,在反序列化中JackJson会将收到的yyyy-MM-dd HH:mm:ssS字符串理解为UTC时区的时间串这会对最终反序列化后的date时间有直接影响。
如果序列化和反序列化的时区不一致,可以再getter和setter上设置不同的时区表示避免因时区不同造成偏差。
如果可以的话最好传递字符串,可以避免处理时区问题。如果必须传递格式化后的时间表示,最好在最后一层的服务处理。
JSON是一种数据格式,JS对象的语法类似,但还是有根本区别。
JSON格式在传输只能传输的一些基本数据类型,如字符串,数字,布尔值。因此,我认为你说的日期类型只是JSON字符串中的数据,如:
无功JSON的=
{
日期:'2013-02-26
10:50
22'}
您可以使用正则表达式来确定的日期格式,如:是否
VAR
REG
=
/
^
\
d
{4}
-
\
d
{
2}
-
\e{2}
\e{2}:\e{2}:\e{2}
$
/;
无功而isDate
=
regtest(jsondate);
提醒(而isDate);
如果你的数组如你所说的这样,可以用下面的方式,其实核心的东西没有变,只是获取的方法不同,
var date = [
{"riqi":"2017-10-19","xinpai_db":"8","xinpai_gz":"8"},
{"riqi":"2017-10-20","xinpai_db":"3","xinpai_gz":"0"},
{"riqi":"2017-10-21","xinpai_db":"0","xinpai_gz":"0"}
]
for(var i=0;i<datelength;i++){
date[i]['riqi']= date[i]['riqi']replace(/-/g,"/");
}
以上就是关于@RequestBody接收Json参数 | 用自定义注解对Vo对象中Date类型日期格式校验全部的内容,包括:@RequestBody接收Json参数 | 用自定义注解对Vo对象中Date类型日期格式校验、json格式数据 "Time":"\/Date(1341417600000+0800)\/" 时间转换、Json转换中Date那点事等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)