【问题标题】:Accessing Static Fields From FreeMarker Template (Spring)从 FreeMarker 模板访问静态字段 (Spring)
【发布时间】:2012-05-22 23:16:15
【问题描述】:

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

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

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

【问题讨论】:

    标签: spring-mvc freemarker templating


    【解决方案1】:

    试试

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

    其中 cfg 是 FreeMarker Configuration 对象。然后您可以使用statics['com.example.ClassName'].FIELD_NAME 访问静态字段或方法。你也可以使用类似的东西

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

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

    【讨论】:

    • 太棒了!但我想在应用程序启动时执行此操作,以便立即可用,什么更好?我做的过滤器 request.setAttribute("globals", ((BeansWrapper) cfg.getObjectWrapper()).getStaticModels().get("com.ums.common.Global"));或者有一些好的方法肯定会有
    • 您可以使用cfg.setSharedVariable("globals", ((BeansWrapper) cfg.getObjectWrapper()).getStaticModels().get("com.ums.common.Global")) 在应用程序启动时配置 FreeMarker。只有在Configuration 对象的objectWrapper 属性具有其最终值之后才小心执行此操作,否则您的应用将无缘无故地同时使用两个包装器。
    【解决方案2】:

    您可以创建 Spring 配置类来配置 Freemarker 并使用 Freemarker configuration.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 静态方法会很有用。

    【讨论】:

      猜你喜欢
      • 2016-05-01
      • 2021-07-27
      • 2019-10-31
      • 1970-01-01
      • 2015-09-11
      • 2016-12-14
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      相关资源
      最近更新 更多