Struts 1 中“日期类型”的表单数据处理

来源:互联网 发布:合肥seo整站优化 编辑:程序博客网 时间:2024/05/17 15:39

在表单中填写日期是个很常见的情况。

在Struts 1的ActionForm中,可以根据要提交的表单数据创建对应的ActionForm Bean属性,属性的类型支持Java的基本数据类型及其包装类,还有字符串,也就是说如果你将ActionForm Bean的属性类型设为(int),Struts会自动将无法正常转换为int类型的数据都转换为0(如果属性类型为包装类,则可能得到null),可以用于实现第一层次的表单数据过滤。

但是我们应该明白,表单数据本质上全部都是文本字符,Struts只不过是帮我们做了一步自动转换。当然只是简单的数据类型转换,但如将一个字符串"2007-12-5"转换为java.util.Date类型,Struts则没有提供直接的支持了,再说日期字符串的解析本身就是一个情况复杂的事情,因为这个“日期字符串”也没有固定的模式(当然我们最常见的模式在Java中应该是"yyyy-MM-dd"了)。

于是我们若要在表单中处理日期类型的数据,必须自己设计一种解决方案。

方案1:在ActionForm Bean中,日期直接当作字符串处理。
这样做的话,在每次从ActionForm Bean中取数据时,都需要手动进行一次日期字符串的解析,非常麻烦

方案2:在ActionForm Bean中,对应表单的属性类型仍作字符串处理,但提供一对辅助Getter/Setter方法,分别提供对此属性的解析/格式化处理。
这样做又能保持ActionForm Bean的兼容性(所有的属性数据类型都是Struts自动转换所支持的),又能很方便地取得解析后的日期类型的数据。

方案3:直接提供java.util.Date类型的属性及其Getter/Setter。但是这样做在提交表单的时候会出错,因为Struts无法将一个字符串参数传给一个需要java.util.Date类型参数的Setter。所以我们稍作改造,将Setter参数类型改为java.lang.String,并在其方法体中进行日期字符串的解析。

下面比较一下3种方案的利弊:

方案1做法没有什么不妥,就是麻烦了点。当然如果你的项目不大,处理数据时直接采用SQL语句,或者是数据库中本来就是使用VARCHAR等类型来保存“日期”的,那么这样做也可以,无需进行类型解析转换。

方案2则优点较多:属性本身采用字符串类型,能够保存表单提交的原始数据。需要日期类型时只需根据情况调用辅助用的Getter,调用辅助用Setter时,又可以自动格式化日期字符串。同时仍然可以使用属性原配的Getter/Setter来处理实际提交的字符串。不足之处:对应每个日期属性都需要多增加两个方法(不过是一次编写,可反复调用:),然后日期的解析是否会带来运行效率问题?(我感觉几乎可以完全忽略……)

方案3只是效果能够实现,缺点多多:表单提交的原始数据丢失,因为在调用Setter的时候便进行了解析,如果解析不成功,我们必须要舍弃非法格式的数据,并给日期类型的属性对应的成员变量一个“默认值”,那么这个“默认值”使用什么好呢?null?1900-1-1?这里可不能抛出异常,否则Struts在提交表单的时候问题可大了。还有你见过Getter和Setter类型不一致的Bean属性吗?好像不符合规范,又让人感觉怪怪的,很是罪过,我们要剔除掉奇怪的代码以免影响开发人员的心情!

最后,因为方案2保存了原始数据,所以可以很方便地在validate方法中判断原始输入是否合法;而方案3则难以处理判断了,因为它在Set的时候就已经把原始数据给过滤了。
有人说Struts配套的插件Validator框架?那个我就不考虑了,它默认的日期模式是“yyyy/MM/dd”不合我意,然后其验证过程仍然是调用Getter然后解析字符串,并不能给我提供将字符串转换为日期的便利方式。

所以我推荐方案2

ps:日期的解析和格式化请参考“java.text.SimpleDateFormat

原创粉丝点击