昨天项目中遇到一个棘手的问题。是关于日期格式的。 前端
项目是前端Delphi,后端Play 1.x。在进行数据交互的时候。日期有两种格式,长格式:yyyy-MM-dd HH:mm:ss,短格式:yyyy-MM-dd。java
在Play 框架对请求过来的数据进行参数绑定的时候,会将请求中的K/V字串转换为对象中规定的类型。好比日期类型Date。 Play中是支持配置统一的转换格式,在conf/application.conf中:后端
# Date format # ~~~~~ date.format=yyyy-MM-dd # date.format.fr=dd/MM/yyyy
可是,这里会有个问题。由于Play参数绑定中日期的处理是用的java.text.SimpleDateFormat类。 数据结构
若是是在Application.conf中配置的是短格式,那么若是请求是长格式的,时分秒就会被抹掉,归零。 但是若是配置长格式,那么短格式由于格式不正确,SimpleDateFormat中parse方法处理是抛异常,绑定中play会将该字段设为null。 app
一开始没有想到好方法,由于项目刚刚从EJB+SSH 转移到Play 1.x上,稳定跑起来是第一,不宜动刀去修改原来的数据结构。本还想修改play的源码,并且play的日期绑定类DateBinder也至关简单,以下框架
public class DateBinder implements TypeBinder { public static final String ISO8601 = "'ISO8601:'yyyy-MM-dd'T'HH:mm:ssZ"; public Date bind(String name, Annotation[] annotations, String value, Class actualClass, Type genericType) throws Exception { if (value == null || value.trim().length() == 0) { return null; } Date date = AnnotationHelper.getDateAs(annotations, value); if (date != null) { return date; } try { SimpleDateFormat sdf = new SimpleDateFormat(I18N.getDateFormat()); sdf.setLenient(false); return sdf.parse(value); } catch (ParseException e) { // Ignore } try { SimpleDateFormat sdf = new SimpleDateFormat(ISO8601); sdf.setLenient(false); return sdf.parse(value); } catch (Exception e) { throw new IllegalArgumentException("Cannot convert [" + value + "] to a Date: " + e.toString()); } } }
可是框架一动,就动全身了。 在Google了不少也没有方法。问Play的QQ群也没有好方法。最后在刷官方文档中发现解决方法。就是As标签,官方中是这样使用。this
public static void articlesSince(@As("dd/MM/yyyy") Date from) { List<Article> articles = Article.findBy("date >= ?", from); render(articles); }
由于项目是从SSH中迁过来,因此对象中仍是setter/getter模式,将As加在setter方法上能成功,加在setter的形参上则不能。spa
@As("yyyy-MM-dd HH:mm:ss") public void setDepartdatetime(Date departdatetime) { this.departdatetime = departdatetime; }
从这个BUG的解决方法来讲,并无什么技术含量或者说难度,可是问题的关键是问了这么多人也没人知道,只能说太忽略基础了……code