【slim3】日付型のvalidation【Struts】
今更なんですが、日付型データの validation で躓いたのでメモしておきます。
※Struts 由来のものなのですが、slim3 でも同様なので、一応 GAE/J の slim3 カテゴリにしています。
1.具体的な事象
日付型の validation では、"yyyy/MM/dd" などのフォーマットを指定できる dateType を使用するかと思います。
この dateType ですが、
- "2010/01/03" : OK
- "2010/1/3" : OK(前のゼロがなくてもOK)
- "2010/01/32" : NG(存在しない日付)
- "2010/01/a@" : NG(数値ではない)
になるのはわかります。
ですが、"2010/01/3a" と指定するのはOKだったりします。
2.原因
dateType で使用している SimpleDateFormat#parse() が、ParsePosition を指定していないためです。
"2010/01/3a" の "a" 以前までが日付として解釈され、"a" が切り捨てられます。
そのため、今回の場合では、値が "2010/01/3" と「誤認識」されます。
3.考えられる影響
ユーザによっては、この箇所だけではなく、全体的な品質に問題のあるシステムなのではと誤解されるケースもあり得ます。(私の場合、実際そうでした。)
また、validation はOKでも、後続の処理でのデータ変換で想定外の例外が起こる可能性もあります。
4.対処方法
dateType と一緒に、正規表現のチェックも追加すると良いです。
Struts なら mask、slim3 なら regexp を追加します。
※正規表現チェックだけですと、数値部分が日付として妥当かをチェックすることが面倒なので、dateType とセットにした方が無難かと思います。
5.具体例(slim3)
Validators v = new Validators(RequestLocator.get()); v.add("date", v.dateType("yyyy/MM/dd")); v.add("time", v.dateType("HH:mm"));
↓
Validators v = new Validators(RequestLocator.get()); v.add("date", v.dateType("yyyy/MM/dd"), v.regexp("^\\d{4}/\\d{2}/\\d{2}$")); v.add("time", v.dateType("HH:mm"), v.regexp("^\\d{2}:\\d{2}$"));