2.3.27 (在 Apache 孵化)

Page Contents

发布日期:2017-11-03

这是一个稳定的最终版本. 在该项目成为完全被接受(分级)的 Apache 项目之前,Apache Software Foundation 要求使用“ incubating”后缀。

FTL 方面的更改

  • 新指令:continue(sf.net #79FREEMARKER-37)。可以在list指令内部使用它来跳到下一个迭代(类似于 Java)。 See more...

  • &&(逻辑“和”)运算符添加了替代语法:\and&&。这些是为了解决应用程序中的问题,这些应用程序中的模板必须是有效的 XML(在大多数情况下&&是无效的 XML/HTML),或者 Importing 的模板是在 XML 或 HTML 转义后存储的。请注意,由于向后兼容性,无法识别孤独的&和不具有\and

  • 新内置的sequence(FREEMARKER-73)。这可用于解决以下情况:可列出的值缺少模板中需要的某些功能(例如无法两次列出,无法确定其大小等),并且您无法修改数据模型来解决问题。 See more...

  • 已修复的错误(FREEMARKER-70):解析器不允许在字符串 Literals 表达式内插值(如<#list 1..3 as loopVar>${'${loopVar?index}'}</#list>)中使用解析器内置的循环变量(如loopVar?index),它表示作用域内没有loopVar名称的循环变量。

  • 修正了错误:解析器不允许在switch标签和第一个case标签之间进行 Comments。

  • 已修复的错误(FREEMARKER-71):使用exp?eval时,如果求值字符串中的表达式引发异常,则该异常的原因异常将丢失。

Java 方面的更改

  • 添加了新的配置设置(FREEMARKER-48),wrap_unchecked_exceptions(Configurable.setWrapUncheckedExceptions(boolean))。如果为true,则在评估表达式或执行自定义指令期间引发的未经检查的异常将被包装为TemplateException -s。这样做的好处是,异常将包括模板中的位置(而不仅仅是 Java 堆栈跟踪),并且TemplateExceptionHandler也将为此调用。当此设置为false(这是向后兼容的默认值)时,未经检查的异常将冒泡并由Template.process抛出,就像在早期版本中一样。 (请注意,无论此设置如何,从模板调用的普通 Java 方法始终将抛出的异常包装到TemplateException中.)

  • 添加了新的配置设置attempt_exception_reporter(Configurable.setAttemptExceptionReporter(AttemptExceptionReporter)),以允许自定义报告attempt directive处理(并因此抑制)异常的方式。缺省AttemptExceptionReporter会将异常记录为错误,就像在早期版本中一样,尽管现在错误消息将指示该异常是在attempt指令块内引发的。

  • 添加了新的BeansWrapper设置preferIndexedReadMethod。添加此代码是为了解决 Java 8 兼容性问题。有关更多信息,请参见下面的错误修复条目。

  • incomplatible_improvements设置为 2.3.27(或更高版本)时,在评估表达式或调用指令时抛出以下未检查的异常(但不是它们的子类)将被包装到TemplateException -s 中:NullPointerExceptionClassCastExceptionIndexOutOfBoundsExceptionInvocationTargetException。此操作的目标与将wrap_unchecked_exceptions设置为true的目的相同(请参见前面的内容),但是它具有向后兼容性,因为它避免包装某些应用程序可能专门捕获的未检查的异常(例如,特定于应用程序的未检查的异常) 。 (与FREEMARKER-48有关。)

  • 修正了错误:从 Java 8 开始,当同一个 JavaBeans 属性同时具有非索引读取方法(如String[] getFoos())和索引读取方法(如String getFoos(int index))时,BeansWrapperDefaultObjectWrapper错误地使用了索引读取方法来访问该属性。这是一个问题,因为数组大小未知,因此该属性在 Java 8 上突然变得无法列出(即<#list myObject.foos as foo>失败)。要启用此修复程序(它将使用非索引读取方法),应将使用的DefaultObjectWrapperBeansWrapperincompatibleImprovements构造函数参数的值增加到 2.3.27. 请注意,如果您将Configurationobject_wrapper设置保留为默认设置,则足以将ConfigurationincompatibleImprovements setting增加到 2.3.27,因为默认设置object_wrapper继承了该设置。如果不能增加incompatibleImprovements(由于它带来的其他更改),则可以将对象包装的preferIndexedReadMethod属性设置为false。请注意,此错误在 Java 8 之前尚未浮出水面,因为java.beans.Inrospector仅在同时存在两种读取方法时才公开非索引方法。

  • 已修复的错误(影响 Java 8 及更高版本):无论preferIndexedReadMethod设置的值如何(请参见上一点),如果索引读取方法和非索引读取方法之一均不可访问(即,在非公共声明中进行声明)类型,并且未由公共类型继承),虽然其他读取方法是可访问的,但我们将使用可访问的方法。以前,如果有一个索引读取方法但无法访问,则我们已经放弃了,并且该 bean 属性不可见。这样的属性现在将再次可见,就像 Java 8 之前一样。(在 Java 8 java.beans.Inrospector之前仅公开了这种情况下的非索引读取方法,因此我们没有这个问题.)

  • 错误修正:在 OpenJDK 9(但未在早期版本上,在 Oracle Java 9(未通过“内部版本 9 181”测试)上)尝试使用基于 DOM 的 XML 支持(freemarker.ext.dom.NodeModel)时,除非您碰巧拥有 Apache 在 Classpath 中的 Xalan 中,NodeModel构造函数将以IllegalAccessError失败,因为“ java.xml 不会导出 com.sun.org.apache.xml.internal.utils”。请注意,尽管在 2.3.27 中不再引发该异常,但 FreeMarker 无法使用 OpenJDK 9 中包含的 XPath 支持,因此尝试使用 XPath 表达式的模板(如doc['//foo'])仍将失败,除非存在第三方 XPath 支持

  • 错误修正:TemplateExceptionHandler抑制(即不重新抛出)异常时,attempt directive将不再记录该异常。 (确切地说,不再为AttemptExceptionReporter调用它;默认的一个记录为错误.)

  • 已修复的错误(属于FREEMARKER-48的一部分):当表达式中发生算术异常(通常被零除)时,模板处理将ArithmeticException照原样抛出,而没有将其打包为TemplateException。因此,在异常中看不到模板中的错误位置。

  • 现在,由于attempt directive块中的错误而记录错误时,日志消息现在指示该错误位于attempt块中。

  • 已修复的错误(FREEMARKER-52):从PropertiessetSetting(String, String) API 设置output_format时,无法识别XHTMLOutputFormat的缩写(例如,在.properties文件中,output_format=XHTMLOutputFormat不起作用,只有output_format=freemarker.core.XHTMLOutputFormat()起作用)。

  • 错误修正:从PropertiessetSetting(String, String) API 设置new_builtin_resolver时,它无法识别allowed_classestrusted_templates关键字的驼峰大小写形式,并抛出异常。现在也可以使用allowedClassestrustedTemplates

  • 错误修正:JSP 支持人员并未尝试使用线程上下文类加载器来加载 TLD,而是仅使用了 FreeMarker 类的定义类加载器。在极少数情况下,这会引起问题,其中freemarker.jar的安装范围比 Web 应用程序高(例如在 Servlet 容器级别),但是 Web 应用程序包含 TLD。

  • Constants.EMPTY_HASHGeneralPurposeNothing(missingVar!的值)现在实现TemplateHashModelEx2。先前它们只是TemplateHashModelEx -s。

  • 已添加Constants.EMPTY_KEY_VALUE_PAIR_ITERATOR

  • 访问 JavaBean 属性(FREEMARKER-80)时,同步少了一些。问题在于java.beans.PropertyDescriptor.getReadMethod方法已同步,并且每次读取属性时freemarer.ext.beans.BeanModel都已调用它。现在,仅在第一次自检该类时才调用该方法。

  • 改进/固定的TemplateTransformModel行为(这是旧版界面,在用户代码中使用较少):

  • Writer TemplateTransformModel.getWriter(Writer out, Map args)现在可以按原样返回out参数,因为 FreeMarker 现在可以识别出它是同一个对象,因此在结束标记之后不会对其调用close()

    • incomplatible_improvements设置为 2.3.27(或更高版本)并且返回的Writer实现TransformControl时,内部用于流控制的异常(用于<#return><#break>等)将不再传递给TransformControl.onError(Throwable)。较早的时候,如果onError没有抛出异常(尽管几乎所有实现都抛出了异常),则您无法在转换后的块中使用上述指令。
  • 加载 FreeMarker jar 中包含的资源时,针对“ IllegalStateException:zip 文件已关闭”和“ ZipException:ZipFile 已关闭”问题(由 FreeMarker 外部的错误引起)添加了解决方法(请参见freemarker.template.utility.ClassUtil.loadProperties)。