【问题标题】:Trouble with using Freemarker to formate Date for GeoServer GetFeatureInfo使用 Freemarker 为 GeoServer GetFeatureInfo 格式化日期的问题
【发布时间】:2020-06-30 08:49:01
【问题描述】:

我在尝试使用 Freemarker 模板以所需格式显示日期时遇到了一些问题。

我将带有日期信息的点存储在 PostGIS 数据库中,该数据库是通过 FME 进程以 ISO 格式 (%Y-%m-%d) 编写的,以便在具有 GeoServer 的启用时间的 WMS 中使用它们。

调用 GetFeatureInfo 时,日期显示为以下格式 10/4/12 12:00 AM,此处应为 2012-10-04。我们已经将服务器设置更改为 -Dorg.geotools.localDateTimeHandling=true -Duser.country=DE -Duser.timezone=GMT -Duser.language=de。

由于这没有给出预期的结果,我们使用 Freemarker 模板进行了尝试。这个想法是检查日期格式的属性并相应地格式化它们。不知何故,我无法让它工作。我试过这个:

<#if attribute.is_unknown_date_like>
${attribute.value?string("YYYY-MM-DD")}
<#else>
${attribute.value}
</#if>

我收到一条关于条件开始的行的错误消息:

freemarker.core.ParseException

我怎样才能使这个条件语句起作用?

【问题讨论】:

  • 错误信息的其余部分是什么?它包含问题所在。另外,freemarker.core.ParseException 表示模板在语法上是错误的,因此它与日期格式无关。你展示的片段也没有这样的问题,所以原因在别处,或者你没有粘贴实际的片段。
  • 也就是说,片段确实还有其他问题(比如你应该使用attribute?is_date_like,带有?),但首先让我们摆脱解析异常。
  • @ddekany - 我发布了我添加到 Freemarker 模板的片段,无需此添加即可工作。所以原因必须在这个片段中。你是对的,我应该使用attribute?is_data_like?,因为它是内置的。有了这个,错误消息变得更加重要。请参阅答案下方的评论。
  • 您使用的 FreeMarker 版本是否可能低于 2.3.21?那是添加is_date_like 的时候。试试${.version}。那你真的需要升级了。
  • 你得到attribute.value 作为字符串吗?我相信它是java.util.Date,但您最近的“答案”表明它只是一个字符串。那么你就不需要?is_date_like,因为无论如何它总是false

标签: date datetime freemarker geoserver getfeatureinfo


【解决方案1】:

@ddekany,你说得对,对不起。今后我会牢记这一点!

所以我尝试了你的建议,如上所述,使用 ? 仍然会返回错误消息,但它变得更加重要。

2020-07-01 08:19:02,521 ERROR [geoserver.ows] - freemarker.core.ParseException: Error on line 29, column 46, in template content.ftl Found is_date_like, expecting one of: is_directive, parent, js_string, j_string, uncap_first, is_transform, number, is_hash, trim, children, has_content, iso_ms, xml, iso_utc, byte, double, left_pad, matches, capitalize, number_to_datetime, contains, size, iso_local_h_nz, iso_utc_ms, iso_local_m_nz, is_collection, long, default, iso_utc_h_nz, iso_local_ms, is_boolean, last_index_of, c, iso_utc_m_nz, is_macro, rtf, iso_utc_nz, upper_case, node_name, reverse, cap_first, url, is_hash_ex, iso_nz, is_enumerable, exists, number_to_date, first, iso_local, date, iso, replace, float, right_pad, datetime, node_type, split, iso_ms_nz, number_to_time, is_sequence, iso_utc_m, html, ancestors, iso_utc_h, iso_local_ms_nz, new, last, sort, eval, lower_case, web_safe, is_date, is_string, iso_local_nz, word_list, seq_last_index_of, node_namespace, string, keys, iso_m_nz, values, seq_index_of, chunk, sort_by, iso_m, starts_with, substring, index_of, iso_h, root, floor, iso_h_nz, ceiling, if_exists, chop_linebreak, iso_local_h, length, is_indexable, groups, is_node, iso_local_m, int, iso_utc_ms_nz, xhtml, ends_with, round, interpret, is_method, namespace, short, seq_contains, time, is_number in content.ftl

所以,问题似乎在于内置。正如错误消息中所述,Freemarker 需要 is_date 而不是 is_date_like,尽管在 Freemarker 文档中指出应该使用 is_date_like 而不是 is_date link。所以我用is_date尝试了你的建议。

现在,没有出现错误信息,但日期格式没有改变。

【讨论】:

  • 请编辑您的原始问题,而不是在应该是原始问题答案的内容中添加信息。我会在原问题下回答。
【解决方案2】:

更新:向#else分支等添加解析。

如果您不知道attribute.valuejava.lang.String 还是java.util.Date,您可以这样做:

<#if attribute.value?is_date_like>
${attribute.value?date?string.iso}
<#else>
${attribute.value?date("M/d/yy hh:mm a")?string.iso}
</#if>

如果您知道attribute.value 的类型,那么您只需要执行#if#else 中的内容即可。

如果您使用的是真正旧版本的 FreeMarker,则必须使用 ?string("yyyy-MM-dd") 而不是 ?string.iso。另外?is_date_like 可能还不可用,您必须使用attribute.value?is_unknown_date_like || attribute.value?is_datetime || attribute.value?is_date

顺便说一下,如果您通常以 ISO 格式输出日期/时间值,那么有人应该只需将 date_format/time_format/datetime_format 配置设置设置为 iso,然后您可以省略 @987654337 @。 (或者,这些也可以在模板中设置,如&lt;#setting date_format='iso'&gt;等)

【讨论】:

    猜你喜欢
    • 2019-02-17
    • 1970-01-01
    • 2023-03-05
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    相关资源
    最近更新 更多