如何在 Freemarker 模板中访问 Spring 应用程序属性?
Posted
技术标签:
【中文标题】如何在 Freemarker 模板中访问 Spring 应用程序属性?【英文标题】:How to access a Spring application property in a Freemarker template? 【发布时间】:2013-02-24 12:22:40 【问题描述】:我有使用 Spring 3.1 的 Java webapp,带有用于呈现视图的 Freemarker 模板。我想根据特定应用程序属性的真/假值有条件地在视图中显示链接。
我在src/main/resources/application.properties
中定义了以下应用属性:
showLink=true
如果我在 Spring MVC 中使用常规 JSP,我可以使用 SpEL 根据 showLink
的值有条件地显示链接:
<c:if test="$configuration['showLink']">
<a href="...">some link</a>
</c:if>
如何在 Freemarker 模板中执行此操作?我尝试做这样的事情,但无法让它工作:
<#assign showLink>$configuration['showLink']</#assign>
<#if showHelpLink>
<a href="...">some link</a>
</#if>
我查看了Spring freemarker macros(在 spring.ftl 中),但我看到的最接近的是获取消息属性的能力,而不是应用程序属性。
我尝试过的方法不起作用
我查看了 spring.ftl 中的宏,但最接近的是给我消息属性。
另外,我无法将值注入控制器,然后将其放入ModelMap
,因为我的 FreeMarker 模板是所有页面的标题,因此它会自动导入:
<bean id="abstractFreemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" abstract="true">
...
<property name="freemarkerSettings">
<props>
<prop key="auto_import">
/spring.ftl as spring, /myTemplate.ftl as myTemplate
</prop>
</props>
</property>
...
</bean>
我还没有尝试过的事情
我发现了一个 blog post,描述了如何手动将 SpEL 支持添加到 Freemarker。对于我需要它的这种情况,我宁愿不做所有这些。
创建一个自定义标签库来检索应用程序属性值,所以我可以在我的 freemarker 模板中做这样的事情:
<#assign showLink><foo:getAppProperty name="showLink"/></#assign>
【问题讨论】:
【参考方案1】:我无法让接受的解决方案正常工作,但如果我使用 context:property-placeholder 而不是 util:properties 加载属性文件,一切都会无缝运行:
替换
<util:properties id="myProperties" location="classpath:/myprops.properties" />
与
<context:property-placeholder location="classpath:/myprops.properties" />
我实际上是在尝试从 maven 获取版本,所以我的位置是
META-INF/maven/group.id/artifactid/pom.properties
此外,我发现我必须像这样访问 freemarker 中的变量: $var1、$var2
【讨论】:
如何获得价值? myProperties.someProperty?【参考方案2】:由于某种未知原因,接受的解决方案对我不起作用。我正在使用 bean 加载属性。所以假设存在一个用这个 bean 映射的 Java 类:
<bean id="appProperties" class="com.myCompany.AppProperties">
<property name="appVersion" value="$app.version" />
</bean>
我使用这个 xml 映射访问 Freemarker 中的 bean 变量:
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/views/"/>
<property name="defaultEncoding" value="UTF-8" />
<property name="freemarkerSettings">
<props>
<prop key="auto_import">spring.ftl as spring</prop>
<prop key="number_format">0.####</prop>
</props>
</property>
<property name="freemarkerVariables" ref="staticAttributesMap"/>
</bean>
<util:map id="staticAttributesMap">
<entry key="appversion" value="#appProperties.appVersion" />
</util:map>
不要忘记在 xml 文件的顶部添加相应的命名空间(...是你已经拥有的命名空间,以防你像我一样直到现在才使用 util):
<beans ...
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="...
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
【讨论】:
您能提供您的 AppProperties 吗?我收到Could not resolve placeholder 'client.baseUrl' in value "$client.baseUrl"
【参考方案3】:
我在 spring 中加载属性
<util:properties id="myProperties" location="classpath:/myprops.properties" />
然后在配置中我使用“freemarkerVariables”属性,例如
<bean id="abstractFreemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" abstract="true">
...
<property name="freemarkerVariables" ref="staticAttributesMap" />
<util:map id="staticAttributesMap">
<entry key="var1" value="$var1" />
<entry key="var2" value="$var2" />
<entry key="myMap">
<map>
<entry key="v1" value="$value1" />
<entry key="v2" value="$value2" />
</map>
</entry>
</util:map>
其中 var1/var2/value1/value2 是您文件中的所有属性。
你可以像这样访问freemarker中的属性
$var1$
$var2$
$myMap.v1$
$myMap.v2$
此解决方案的唯一缺点是,Freemarker 不会自动使用属性。你需要添加你想要的。
【讨论】:
是的,这行得通。实际上,我刚刚在我正在研究的 webapp 中找到了一个示例,它已经在这样做了!模板中的代码如下所示:render some link#if> 你能展示一下你的文件(myprops.properties)是什么样子的吗?因为,当我访问像 $var1 这样的 var 时,我得到了相同的值,这是很自然的,因为这个值来自配置文件,而不是来自 myprops。 好的,已经解决了。只是缺少以上是关于如何在 Freemarker 模板中访问 Spring 应用程序属性?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Freemarker 模板中访问 Spring 应用程序属性?
我的 Freemarker ObjectWrapper 如何访问模板设置