0

我们有

  1. 一台服务器 A 在 Jboss EAP6/Windows/US 上运行
  2. 在 Jboss EAP6/Linux/South America 上运行的另一台服务器 B

当前的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,我认为它能够支持国际化,对吧?

4

1 回答 1

0

搞定了。

问题主要是因为String转换Date,它要么是

  1. 对象中定义的格式DateFormat与日期字符串值不匹配,或者
  2. 当前服务器环境无法通过其当前语言环境识别时区代码或其他时间格式

所以

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 框架上,所以问题的原因是:我没有完全 100% 关注这个帖子,所以

@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

LocaleContextHolder.getLocale()从 sortFormat 启动中删除了它,然后它就像一个魅力。当表单将日期字符串从 UI 返回到控制器时,似乎我们必须摆脱 System local 来转换日期字符串。

可以的原因是因为 printFormat 在将日期信息放入 UI 时已经处理了语言环境

DateFormat printFormat = new SimpleDateFormat(DateTimeFormat.patternForStyle("S-", LocaleContextHolder.getLocale())); // format for joda time dojo UI

因此,一旦从 UI 中返回 Date 字符串,就没有必要在任何前面使用语言环境进行处理,我们应该可以为 sortFormat 取出语言环境。这就是我的猜测。

干杯。

于 2013-05-29T21:48:04.543 回答