我们有
- 一台服务器A运行在Jboss EAP6/Windows/US上
- 另一个服务器B运行在Jboss EAP6/Linux/South America
当前的spring应用程序,有一个UI页面传递一个日期选择框,当点击提交时,这个日期对象将作为java bean的字段传递到下一页。
现在的情况是:
服务器A运行此表单没有问题,但是服务器B在提交时抛出异常:
nested exception is java.lang.IllegalArgumentException:
Unparseable string: [Unparseable date: "Wed May 29 16:34:58 ART 2013",
Unparseable date: "Wed May 29 16:34:58 ART 2013"]]
似乎服务器B不知道如何处理数据格式作为Wed May 29 16:34:58 ART 2013
,即使我添加了@initBinder
@InitBinder
public void registerDateBinder(WebDataBinder binder) {
DateFormat printFormat = new SimpleDateFormat(DateTimeFormat.patternForStyle("S-", LocaleContextHolder.getLocale())); // format for joda time dojo UI
printFormat.setLenient(false);
DateFormat sortFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy" , LocaleContextHolder.getLocale()); // format for whatever return from form
sortFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new ExpandableCustomDateEditor(printFormat, Arrays.asList(printFormat, sortFormat), true));
}
ExpandableCustomDateEditor
来自本文
上面有趣的部分是当Date对象是bean的字段时发生的问题
public String showSecondView(Form aForm,
Model uiModel) {
.....
}
但这在另一个没有@InitBinder的控制器中没有问题
public String list(Model uiModel,
@RequestParam(value = "fromDate", required = false) Date fromrDate,
.....)
....
}
但是为什么这个错误仍然发生,即使有@initBinder?我以前发过帖子,似乎平台有不同的方式来翻译timezone
代码,但是Spring,我认为它有能力支持国际化对吗?
成功了。
问题主要是由于String
到Date
的转换,它要么
-
DateFormat
对象中定义的格式与日期字符串值不匹配,或者 - 当前服务器环境无法通过其当前区域设置识别时区代码或其他时间格式
solution to issue1: find the correct Date format, google is best friend
solution to issue2: remove locale from current `DateFormat` object, only use
DateFormat df = new DateFormat(String pattern);
instead of
DateFormat df = new DateFormat(String pattern, Locale aLocale);
when convert String to Date from what return from form
在我的情况下,因为我们是在Spring框架上,所以问题的原因是:我没有百分百关注这个帖子,所以
@InitBinder
public void registerDateBinder(WebDataBinder binder) {
DateFormat printFormat = new SimpleDateFormat(DateTimeFormat.patternForStyle("S-", LocaleContextHolder.getLocale())); // format for joda time dojo UI
printFormat.setLenient(false);
DateFormat sortFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy" , LocaleContextHolder.getLocale()); // NO LOCALE PlEASE!!!!!!
sortFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new ExpandableCustomDateEditor(printFormat, Arrays.asList(printFormat, sortFormat), true));
}
问题在这里
DateFormat sortFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); // AFTER REMOVE LOCALE
我从sortFormat初始化中删除了LocaleContextHolder.getLocale()
,然后它像一个魅力一样工作。当表单从UI返回日期字符串到控制器时,似乎我们必须摆脱系统本地转换日期字符串。
之所以可以,是因为printFormat在将日期信息放入UI
时已经处理了区域设置DateFormat printFormat = new SimpleDateFormat(DateTimeFormat.patternForStyle("S-", LocaleContextHolder.getLocale())); // format for joda time dojo UI
所以一旦Date字符串从UI取回,就没有必要再用locale处理了我们取出sortFormat的locale应该没问题。我也这么想。
欢呼。