How to access a Spring application property in a Freemarker template?

蓝咒 提交于 2019-12-12 10:00:38

问题


I have Java webapp that uses Spring 3.1, with Freemarker templates for rendering the view. I want to conditionally display a link in the view, based on the true/false value of a particular application property.

I have the following app property defined in src/main/resources/application.properties:

showLink=true

If I were using a regular JSP with Spring MVC, I could use SpEL to conditionally display the link based on the value of showLink:

<c:if test="${configuration['showLink']}">
    <a href="...">some link</a>
</c:if>

How do I do this in a Freemarker template? I tried doing something like this, but couldn't get it to work:

<#assign showLink>${configuration['showLink']}</#assign>

<#if showHelpLink>
    <a href="...">some link</a>
</#if>

I looked at the Spring freemarker macros (in in spring.ftl), but the closest thing I see is the ability to get a message property, not an app property.

Things I've tried that didn't work

  1. I looked at the macros in spring.ftl, but the closest it comes is giving me message properties.

  2. Also, I can't inject the value into the controller and then put it into the ModelMap, because my FreeMarker template is the header for all pages so it's auto-imported:

<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>

Things I haven't tried yet

  1. I found a blog post describing how to manually add support for SpEL to Freemarker. I'd rather not do all of that for this one case where I need it.

  2. Creating a custom tag library to retrieve the application property value, so I could do something like this in my freemarker template:

<#assign showLink><foo:getAppProperty name="showLink"/></#assign>

回答1:


I load the properties in spring using

<util:properties id="myProperties" location="classpath:/myprops.properties" />

And then in the config I use the "freemarkerVariables" attribute, e.g.

<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>

where var1/var2/value1/value2 are all properties from your file.

You can the access the properties in freemarker like this

$var1$
$var2$
$myMap.v1$
$myMap.v2$

The only downside with this solution is, properties will not automatically be available to Freemarker. You need to add the ones you want.




回答2:


For some unknown reason, the accepted solution didn't work for me. I was loading properties using beans. So assuming there exists a Java class mapped with this bean:

<bean id="appProperties" class="com.myCompany.AppProperties">
    <property name="appVersion" value="${app.version}" />
</bean>

I access bean variable in Freemarker using this xml mapping:

<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>

And not forgetting to add the corresponding namespaces at the top of the xml file (... are namespaces that you already had, in case you weren't using util until now, like me):

<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">



回答3:


I couldn't get the accepted solution working, but if I loaded the properties-file with context:property-placeholder instead of util:properties everything worked seamlessly:

replace

<util:properties id="myProperties" location="classpath:/myprops.properties" />

with

<context:property-placeholder location="classpath:/myprops.properties" />

I was actually trying to fetch version from maven, so my location was

 META-INF/maven/group.id/artifactid/pom.properties

Furthermore, I found I had to access variables in freemarker like this: ${var1}, ${var2}



来源:https://stackoverflow.com/questions/15302775/how-to-access-a-spring-application-property-in-a-freemarker-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!