Play 1.x 日期格式与参数绑定 (Play 1.x Date Format And Parameter Binding)

本文详细描述了如何在Play框架中解决日期格式匹配问题,包括日期格式配置、源码解析及As标签的使用。重点在于通过配置和标签解决日期格式不匹配导致的数据绑定错误。

昨天项目中遇到一个棘手的问题。是关于日期格式的。 

项目是前端Delphi,后端Play 1.x。在进行数据交互的时候。日期有两种格式,长格式:yyyy-MM-dd HH:mm:ss,短格式:yyyy-MM-dd。

在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。 

一开始没有想到好方法,因为项目刚刚从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标签,官方中是这样使用。

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的形参上则不能。

@As("yyyy-MM-dd HH:mm:ss")
public void setDepartdatetime(Date departdatetime) {
    this.departdatetime = departdatetime;
}


从这个BUG的解决方法来说,并没有什么技术含量或者说难度,但是问题的关键是问了这么多人也没人知道,只能说太忽略基础了……

转载于:https://my.oschina.net/markho/blog/498284

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值