Присвоение даты Freemarker, казалось бы, действительной дате неудачи - PullRequest
1 голос
/ 04 января 2012

У меня странная проблема, которая, кажется, не возникает постоянно, но когда это происходит, это выглядит так:

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 выглядит следующим образом:

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 голосов
/ 04 января 2012

Сообщение об ошибке означает, что внутренне DateFormat.parse выдало java.text.ParseException.Поскольку строка, указанная в сообщении об исключении, должна быть проанализирована в порядке с этим шаблоном (и я надеюсь, что ваш пример точный и реальный), и поскольку это происходит только иногда, она воняет как проблема параллелизма (многопоточности) вокруг формата датыкэш.Если бы вы могли создать автономный тест, который бы продемонстрировал это, это помогло бы найти его быстрее (я отвечаю за поддержание FM, в значительной степени).Быстро просматривая исходный код, ничто не прыгает на меня ... Синхронизация есть.

Редактировать: Другая возможная причина заключается в том, что иногда настройка локали FreeMarker не является английской.Постфикс "AM" / "PM" отличается для неанглийского языка, поэтому он вызывает эту ошибку.

0 голосов
/ 04 января 2012

Ваш код выглядит корректным, я понятия не имею, почему он терпит неудачу - особенно "иногда".

Одна вещь, которая кажется мне странной, это то, что вы сначала конвертируете свою дату в строку (внутри getCreatedTime()), только чтобы проанализировать ее обратно в шаблоне FreeMarker. Почему бы не передать это как дату? Что-то вроде:

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

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