【问题标题】:Freemarker date assignment to seemingly Valid Date FailsFreemarker 日期分配给看似有效的日期失败
【发布时间】:2012-02-01 22:54:57
【问题描述】:

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

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。它似乎大部分时间都可以工作,但有时会失败......

想法?

【问题讨论】:

    标签: java spring templates spring-mvc freemarker


    【解决方案1】:

    错误消息意味着,在内部,DateFormat.parse 已抛出 java.text.ParseException。由于异常消息中给出的字符串应该可以使用该模式进行解析(我希望您的示例是准确和真实的),并且由于它仅偶尔发生,因此它就像日期格式的并发(多线程)问题缓存。如果您可以构建一个独立的测试来证明这一点,那将更快地找到它(我负责维护 FM,几乎)。快速查看源代码,我没有任何反应……同步就在那里。

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

    【讨论】:

    • 我的例子是准确和真实的,除了我已经分别用 foo 和 bar 替换了文件名......我认为你和 ChssPly76 都帮助了我。我同意这可能是一个并发问题。虽然是创可贴的解决方案,但我想我会接受 ChssPly76 的建议,并完全避免使用解析模式。我假设这也可以避免日期格式缓存?
    • 我使用的是 FreeMarker 版本 2.3.16。迁移到新版本可能会有所帮助吗?
    • 它不会避免日期格式缓存,因为它也用于将Date 转换为String。但是,如果问题是特定于 parse 方法的,那么它会避免它。从 2.3.16 升级将无济于事,因为这个错误(如果它是 FreeMarker 错误的话)到目前为止是未知的。
    • 另一个想法是失败的原因......是否有时 FreeMarker“区域设置”设置不是英语?非英语的“AM”/“PM”后缀不同,因此会导致此错误。
    • ddekany -- 您可能正在使用“区域设置”设置。大多数成功的用户来自美国。似乎失败的是来自俄罗斯。我将对此进行进一步调查。谢谢!!如果是这种情况,是否有一种优雅的解析方式?只需省略 'a' 解析标志?
    【解决方案2】:

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

    然而,让我感到奇怪的一件事是,您首先将日期转换为字符串(在 getCreatedTime() 内),只是为了在 FreeMarker 模板中将其解析回。为什么不把它作为日期传递呢?比如:

    // Project.java
    public Date getCreatedTime() {
        return this.createdTime;
    }
    
    // bar.ftl
    <#assign createDate = project.createdTime?datetime>
    

    【讨论】:

    • 感谢您的帮助。根本原因实际上是一些并发问题,我将进一步调查
    猜你喜欢
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 2022-01-01
    相关资源
    最近更新 更多