Play 1.x 日期格式與參數綁定 (Play 1.x Date Format And Parameter Binding)

昨天項目中遇到一個棘手的問題。是關於日期格式的。 前端

項目是前端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

相關文章
相關標籤/搜索