1

我想从 FreeMarker 模板访问静态属性

我有一个类说 Global 它包含静态最终字段,并且这个类不是 FreeMarker 模型的一部分。我想知道是否有办法在我的应用程序启动时将此类添加到 FreeMarker 模型并从 Freemarker 模板访问,如下所示:

${statics["com.ums.common.Global"].Change}
4

2 回答 2

0

尝试

dataModel.put("statics", ((BeansWrapper) cfg.getObjectWrapper()).getStaticModels());  

cfgFreeMarkerConfiguration对象在哪里。然后您可以使用statics['com.example.ClassName'].FIELD_NAME来访问静态字段或方法。你也可以使用类似的东西

dataModel.put("globals", ((BeansWrapper) cfg.getObjectWrapper()).getStaticModels().get("com.ums.common.Global"));    

如果您只想公开该类的常量。

于 2012-05-15T14:31:40.457 回答
0

您可以创建 Spring 配置类来配置 Freemarker 并使用 Freemarkerconfiguration.setSharedVariables()方法来启用从任何​​模板访问静态方法。共享变量对于放置全局属性(例如,从您的application.yaml文件中)也非常有用,因此它们可以从任何模板全局使用。

@Configuration
public class FreemarkerConfig implements BeanPostProcessor {

    @Value("${email.from-address}")         // e.g. from `application.yaml`
    private String emailFromAddress;

    @SneakyThrows         // or use try / catch (if not using lombok)
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof FreeMarkerConfigurer) {
            FreeMarkerConfigurer configurer = (FreeMarkerConfigurer) bean;
            freemarker.template.Configuration configuration = configurer.getConfiguration();
            BeansWrapper objectWrapper = (BeansWrapper) configuration.getObjectWrapper();
            configuration.setSharedVariables(getSharedVariables(objectWrapper));
        }
        return bean;
    }

    private Map<String, ?> getSharedVariables(BeansWrapper config) {
        Map<String, Object> sharedVariables = new HashMap<>();

        // Add global variables
        sharedVariables.put("emailFromAddress", emailFromAddress);

        // Add static support
        TemplateModel statics = config.getStaticModels();
        sharedVariables.put("statics", statics);
        return sharedVariables;
    }

}

设置好配置后,您可以在任何模板(例如${emailFromAddress})中添加对共享变量的访问权限。

要访问静态方法,首先需要链接包含静态方法的类。例如,如果您想对 2 个对象进行更定制的比较,您可能拥有:-

public class FreemarkerUtils {

    /**
     * Compare 2 objects.  Both objects are converted to Strings first of all (empty String if null) and compared.
     */
    public static boolean isEqualTo(Object obj1, Object obj2) {
        String str1 = obj1 != null ? String.valueOf(obj1) : "";
        String str2 = obj2 != null ? String.valueOf(obj2) : "";

        return str1.equals(str2);
    }

}

此静态方法必须在 freemarker 模板中按如下方式分配...

<#assign Util=statics['com.my.package.FreemarkerUtils']>

...并按如下方式使用...

<#if Util.isEqualTo (obj1, obj2)> objects are equal! </#if>

当 Freemarker 对您的特定用例不够强大时,从您的模板中使用这样的 Java 静态方法会很有用。

于 2021-05-26T08:37:42.407 回答