【问题标题】:how to access data in freemarker template with self-defined directive?如何使用自定义指令访问freemarker模板中的数据?
【发布时间】:2013-11-20 05:51:48
【问题描述】:

我有一个要求,我想用 freemaker 实现,我已经知道 freemarker 是如何工作的,就像这样

template.process(dataMap,out);

dataMap包含了我们用来填充模板的数据,当然所有的数据都实现了TamplateModel接口,如果我们使用自定义指令没有区别,因为自定义指令实现了TemplateDirectiveModel,这个接口实现了TemplateModel,我需要做的是访问存储在会话中的数据,然后在我的指令中使用这些数据。像这样<@authCheck> </@authCheck>,我的身份验证数据存储在会话中,所以我需要在我的指令中从会话中获取这些数据。

ps:我使用带有freemarker的springMVC

【问题讨论】:

  • 当您说“存储在会话中”时,您是指网络用户会话吗?您需要从 HTTP 会话中取出所需的任何数据并将其放入您的 dataMap 对象中。

标签: java freemarker directive


【解决方案1】:

模板的运行环境由Environment对象表示,也可以作为TemplateDirectiveModel-s的参数获取,也可以通过静态方法Environment.getCurrentEnvironment()从TLS获取。您可以使用setCustomAttribute(String name, Object value) 将其他对象(例如会话)附加到环境,因此您的指令可以使用env.getCustomAttribute(name) 获取它。

每个Template.process 调用都会在内部创建自己的Environment 对象。要在调用主模板之前访问它,您必须这样做而不是简单地调用Tempalte.process

Environment env = myTemplate.createProcessingEnvironment(root, out);
env.setCustoomAttribute("session", sesssion);
// You can addjust other environment settings here too.
env.process();  // template is called here to render the output

另一种可能性是将会话放入数据模型中。 TemplateDirective-s 可以通过env.getDataModel() 访问数据模型。

【讨论】:

    【解决方案2】:

    注意:我的回答没有直接回答问题。

    正如您提到的,您将 Freemarker 与 Spring-MVC 一起使用,我猜您也使用 Spring-Security,如果不是,建议您这样做。

    这是我在 Freemarker 模板中使用 Spring-Security taglib 的方式。

    <#macro auth expr>
     <#assign security=JspTaglibs["http://www.springframework.org/security/tags"] />
     <@security.authorize access=expr>
      <#nested>
     </@security.authorize>
    </#macro>
    

    上面的宏可以像这样使用:

    <#import "/mywebsitename/foomacro.ftl" as foo>
    <@foo.auth "isAnonymous()">
     <a href="/signup">Signup</a>
    </@foo.auth>
    
    <@foo.auth "hasRole('ROLE_USER')">
     <a href="/profile">Profile</a>
    </@foo.auth>
    

    我也很高兴知道我的方法的弱点,例如我们可以使用其他方法获得更好的性能吗?

    例如,也许这个虚构的代码执行得更好?

    <@foo.authCheck AUTH_OBJ_IN_SESSION "ROLE_USER">
     <a href = '/profile'>Profile</a>
    </@foo.authCheck>
    
    <#macro authCheck authObj role>
     <#if authObj.hasRole(role)>
      <#nested>
     </#if>
    </#macro>
    

    我自己的猜测是,它们并没有太大的不同,因为它们都使用来自用户会话的身份验证对象。那么为什么不使用 Spring-Security 中的经过测试(准备使用)的 taglib?

    附言我通常在我的模板中访问 SESSION 变量,就像模型或请求变量一样,例如${VAR_IN_SESSION}。也许那是因为我在我的 spring 配置中设置了&lt;property name="exposeSpringMacroHelpers" value="true"/&gt;。我也有&lt;property name="exposeSessionAttributes" value="false"/&gt;,它似乎对不提供会话变量没有影响!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-28
      • 2021-11-27
      • 2021-07-27
      • 1970-01-01
      • 1970-01-01
      • 2012-05-24
      • 1970-01-01
      相关资源
      最近更新 更多