Charset issues

Page Contents

与大多数 Java 应用程序一样,FreeMarker 使用“ UNICODE文本”(UTF-16)。尽管如此,在某些情况下它必须处理charsets,因为它必须与可能使用其他各种字符集的外部交换数据。

Importing 的字符集

当 FreeMarker 必须加载模板文件(或未解析的文本文件)时,由于文件只是原始字节序列,因此它必须知道文件的字符集。您可以使用encoding setting指定字符集。仅当 FreeMarker 使用ConfigurationgetTemplate方法加载模板(已解析或未解析)时,此设置才生效。请注意,include directive在内部使用此方法,因此,如果模板包含include指令调用,则encoding设置的值对于已经加载的模板很重要。

encoding设置的 getter 和 setter 方法在第一层(配置)中是特殊的。 getter 方法根据作为参数传递的Locale来猜测返回值;它在将语言环境 Map 到编码的表中查找编码(称为编码 Map),如果在此处找不到语言环境,则返回默认编码。您可以使用配置的setEncoding(Locale locale, String encoding)方法填充编码图。编码 Map 最初为空。默认编码最初是file.encoding系统属性的值,但始终应使用setDefaultEncoding方法设置默认默认值,而不是依赖于此。对于新项目,流行的默认编码是utf-8

您可以通过覆盖模板层或运行时环境层中的encoding设置直接提供字符集(当您将编码指定为getTemplate方法的参数时,您可以覆盖模板层中的encoding设置.)。如果不覆盖它,则有效值将是configuration.getEncoding(Locale)方法针对locale设置的有效值返回的值。

另外,您可以不依赖于这种字符集猜测机制,而可以使用ftl伪指令(如<#ftl encoding="utf-8">)在模板文件本身中指定模板的字符集。

请注意,模板的字符集与临时模板生成的输出的字符集无关(除非封闭软件有意将输出字符集设置为与模板字符集相同)。

输出的字符集

Note:

自 FreeMarker 2.3.1 起,output_encoding设置/变量和url built-in可用。它在 2.3 中不存在。

原则上,FreeMarker 不处理输出的字符集,因为它将输出写入java.io.Writer。由于Writer是由封装 FreeMarker 的软件(例如 Web 应用程序框架)制成的,因此输出字符集由封装软件控制。尽管如此,FreeMarker 仍具有名为output_encoding的设置(从 FreeMarker 版本 2.3.1 开始)。随附的软件应将此设置(设置为Writer使用的字符集),以告知 FreeMarker 输出使用什么字符集(否则 FreeMarker 找不到它)。诸如url built-inoutput_encoding 特殊变量之类的某些功能会利用此信息。因此,如果封闭软件未设置此设置,则无法使用需要了解输出字符集的 FreeMarker 功能。

如果编写使用 FreeMarker 的软件,您可能会想知道应该选择哪种输出字符集。当然,这取决于 FreeMarker 输出的使用者,但是如果使用者对这个问题很灵活,那么通常的做法是使用模板文件的字符集作为输出,或者使用 UTF-8.通常,使用 UTF-8 是更好的做法,因为任意文本可能来自数据模型,该数据模型随后可能包含无法用模板字符集编码的字符。

如果使用Template.createProcessingEnvironment(...)Environment.process(...)而不是Template.process(...),则可以为每个单独的模板处理设置 FreeMarker 设置。因此,您可以为每个模板执行独立设置output_encoding设置:

Writer w = new OutputStreamWriter(out, outputCharset);
Environment env = template.createProcessingEnvironment(dataModel, w);
env.setOutputEncoding(outputCharset);
env.process();