Freemarker日期分配看似有效日期失败

时间:2012-01-03 23:25:08

标签: java spring templates spring-mvc freemarker

我遇到了一个似乎不会一直发生的奇怪问题,但是当它发生时,它看起来像这样:

Error: on line 60, column 31 in foo/bar.ftl
Expecting a date here, found: 2011-12-29 04:37AM
The problematic instruction:
----------
==> assignment: createDate=project.createdTime?datetime("yyyy-MM-dd hh:mma") [on line 60, column 9 in foo/bar.ftl]
----------

Java backtrace for programmers:
----------
freemarker.template.TemplateModelException: Error: on line 60, column 31 in foo/bar.ftl
Expecting a date here, found: 2011-12-29 04:37AM
    at freemarker.core.BuiltIn$dateBI$DateParser.parse(BuiltIn.java:334)
    at freemarker.core.BuiltIn$dateBI$DateParser.get(BuiltIn.java:305)
    at freemarker.core.BuiltIn$dateBI$DateParser.exec(BuiltIn.java:316)
    at freemarker.core.MethodCall._getAsTemplateModel(MethodCall.java:93)
    at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
    at freemarker.core.Assignment.accept(Assignment.java:90)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.MixedContent.accept(MixedContent.java:92)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.Environment.process(Environment.java:190)
    at freemarker.template.Template.process(Template.java:237)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:366)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:283)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:233)
    at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
...

bar.ftl中失败的行看起来像这样:

<#assign createDate = project.createdTime?datetime("yyyy-MM-dd hh:mma")>

Project.java代码中的getter如下所示:

private Date createdTime;
...
public String getCreatedTime() {
    SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd hh:mma");
    return createdTime == null ? null : sm.format(createdTime);
}

所以对我来说,看起来所有内容都正确返回,并且代码设置正确。我正在使用FreeMarker 2.3.16和Spring MVC。它似乎在大多数时间都有效,但有时会失败......

想法?

2 个答案:

答案 0 :(得分:0)

您的代码看起来有效,我不知道它为什么会失败 - 尤其是“有时”。

然而,有一件事让我觉得奇怪,那就是你将你的日期转换为字符串优先(在getCreatedTime()内)只是为了在FreeMarker模板中解析它。为什么不把它作为日期开始传递?类似的东西:

// Project.java
public Date getCreatedTime() {
    return this.createdTime;
}

// bar.ftl
<#assign createDate = project.createdTime?datetime>

答案 1 :(得分:0)

错误消息表示内部DateFormat.parse已抛出java.text.ParseException。因为异常消息中给出的字符串应该用该模式解析好(我希望你的例子是准确和真实的),并且因为它有时只发生,所以它就像日期格式的并发(多线程)问题一样缓存。如果你可以构建一个独立的测试来证明这一点,这将使得更快地找到它(我负责维护FM,非常多)。快速查看源代码没有什么可以跳到我身边......同步就在那里。

编辑:另一个可能的原因是FreeMarker“locale”设置有时不是英文。对于非英语,“AM”/“PM”后缀不同,因此会导致此错误。