Settings(配置设置)
是影响FreeMarker行为的已被命名的值。配置设置有很多,
例如:locale
,number_format
,
default_encoding
,
template_exception_handler
。可以参考
Configuration.setSetting(...)
的Java API 文档
来查看配置设置的完整列表。
配置设置存储在 Configuration
实例中,可以在
Template
实例中被覆盖。比如,在配置中给
locale
设置为 "en_US"
,
那么使用该配置的所有模板中的
locale
都使用 "en_US"
,
除非在模板中locale被明确地设置成其它不同的值(参见
localization)。
因此,在 Configuration
中的值充当默认值,
这些值在每个模板中也可以被覆盖。在 Configuration
或 Template
实例中的值也可以在单独调用
Template.process
方法后被覆盖。
对于每个调用了 freemarker.core.Environment
对象的值在内部创建时就持有模板执行的运行时环境,也包括了那个级别被覆盖了的设置信息。
在模板执行时,那里存储的值也可以被改变,所以模板本身也可以设置配置信息,
比如在输出中途来变换 locale
设置。
配置信息可以被想象成3层(Configuration
,
Template
,Environment
),
最高层包含特定的值,它为设置信息提供最有效的值。
比如(设置信息A到F仅仅是为这个示例而构想的):
Setting A | Setting B | Setting C | Setting D | Setting E | Setting F | |
---|---|---|---|---|---|---|
Layer 3: Environment |
1 | - | - | 1 | - | - |
Layer 2: Template |
2 | 2 | - | - | 2 | - |
Layer 1: Configuration |
3 | 3 | 3 | 3 | - | - |
配置信息的有效值为:A=1,B=2,C=3,D=1,E=2。
而F的设置则是 null
,或者在你获取它的时候将抛出异常。
我们看看如何准确设置配置信息:
-
Configuration
层: 原则上设置配置信息时使用Configuration
对象的setter方法,例如:Configuration myCfg = new Configuration(Configuration.VERSION_2_3_23); myCfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); myCfg.setDefaultEncoding("UTF-8");
在真正使用
Configuration
对象 (通常在初始化应用程序时)之前来配置它,后面必须将其视为只读的对象。在实践中,比如很多Web应用框架中,就应该使用这种框架特定的配置方式来进行配置, 比如使用成对的
String
来配置(像在.properties
属性配置文件中那样)。 在这种情况下,框架的作者大多数使用Configuration
对象的setSetting(String name, String value)
方法。 这可以参考setSetting
的API文档 部分来获取可用的设置名和参数的格式的信息。 而在Spring框架中,我们可以这样进行:<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="freemarkerSettings"> <props> <prop key="incompatible_improvements">2.3.23</prop> <prop key="template_exception_handler">rethrow</prop> <prop key="default_encoding">UTF-8</prop> </props> </property> </bean>
请注意,这种形式的配置(
String
键-值对) 和直接使用Configuration
的API相比, 很不幸地被限制了。 -
Template
层:对于被请求的本地化信息,模板的locale
设置由Configuration.getTemplate(...)
来设置。 否则,就不能在这里进行设置,除非想控制Template
对象来代替freemarker.cache.TemplateCache
,这样的话, 应该在Template
对象第一次被使用前就设置配置信息, 然后就将Template
对象视为是只读的。 -
Environment
层:这里有两种配置方法:-
使用Java API:使用
Environment
对象的setter方法。当然想要在模板执行之前来做,然后当调用myTemplate.process(...)
时会遇到问题, 因为在内部创建Environment
对象后立即就执行模板了, 导致没有机会来进行设置。这个问题的解决可以用下面两个步骤进行:Environment env = myTemplate.createProcessingEnvironment(root, out); env.setLocale(java.util.Locale.ITALY); env.setNumberFormat("0.####"); env.process(); // process the template
-
在模板中(通常这被认为是不好的做法)直接使用
setting
指令,例如:<#setting locale="it_IT"> <#setting number_format="0.####">
在这层,当什么时候改变配置信息,是没有限制的。
-
要知道 FreeMarker 支持什么样的配置信息还有它们的意义, 可以先看看FreeMarker Java API文档中的下面这部分内容:
-
在三层中
freemarker.core.Configurable
的setter方法来配置。 -
只在
Configuration
层可用的freemarker.template.Configuration
的setter方法来配置。 -
在三层中可用
String
键-值对书写的freemarker.core.Configurable.setSetting(String,String)
配置。 -
只在
Configuration
层中可用String
键-值对书写的freemarker.template.Configuration.setSetting(String, String)
配置。