无法访问 freemarker 模板中的会话属性

Posted

技术标签:

【中文标题】无法访问 freemarker 模板中的会话属性【英文标题】:Not able to access session attributes in freemarker templates 【发布时间】:2014-07-31 12:28:52 【问题描述】:

我有一个设置会话属性AB 的操作类。我知道价值观是存在的,但它们不是null

在 Freemarker 模板中,我尝试使用以下表达式获取这些值

<#if session.A?exists>
  $session.A
</#if>

<@s.property value="%#session.A" />

在得到以下错误,

<#if session.A?exists> Expression session is undefined on line 39

据我所知 Freemarker Struts2 ,我们不需要做任何额外的设置,因为 Freemarker 的 jar 与 Struts2 捆绑在一起,我认为 Freemarker 将可以访问值堆栈,但似乎我在这里弄错了.有人可以看看我错过了什么吗?我在 S2 2.15.3

以下是附加代码,在动作类中,我向会话对象添加值,

sessionMap.put("A", A);
        sessionMap.put("B", B);
        System.out.println("Inside loop test 2!");           
        String[] args = null;
        SendEmail.main(args);           
        return "success";

现在 sendEmail 类包含 freemarker 配置,

Configuration cfg = new Configuration();
            cfg.setClassForTemplateLoading(SendEmail.class, "");
            Template template = cfg.getTemplate("SendEmail.ftl");              
            Map<String,String> rootMap = new HashMap<>();
            Writer out = new StringWriter();
            try 
                template.process(rootMap, out);
             catch (TemplateException | IOException templateException) 
                logger.error("Freemarker Template processing exception", templateException);
            
            body.setContent(out.toString(), "text/html");
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(body);
            message.setContent(multipart, "text/html");
            Transport.send(message);

会话映射声明为

 private Map<String, Object> sessionMap;

【问题讨论】:

【参考方案1】:

freemarker 中没有 session 对象,你应该这样做

<#assign session = stack.findValue('#session')/>

要执行的动作代码是

FreemarkerResult fr = new FreemarkerResult("SendEmail.ftl");
ActionContext.getContext().getContainer().inject(fr);
Writer out = new StringWriter();
fr.setWriter(out);
Map<String, Object> session = ActionContext.getContext().getSession();
session.put("A", A);
session.put("B", B);
fr.execute(ActionContext.getContext().getActionInvocation());

【讨论】:

让我检查一下再回来 它不工作,我知道会话中有值,在我调用freemarker模板之前,我调用jsp并输出会话值,在那里我可以看到值,$A;$B ;,但相同 你是怎么使用ftl的,你返回的是什么结果类型。发布struts.xml。你也可以试试$stack.findValue('#session.A') 我的结果类型不是 FTL,而是 jsp,我发送了电子邮件,并且该电子邮件模板是 FTL。我将会话值存储在值堆栈中,然后想在 FTL 模板中访问这些值。我有触发电子邮件类的操作类,在该电子邮件类中,我加载 FTL 模板并进行所需的处理,一旦发送电子邮件。一切正常,只是在 FTL 模板中我没有得到值。但是值在已配置 jsp 结果类型。 贴出你在做什么的代码,代码应该是一个独立的例子。你可以在那里访问一个值堆栈吗?【参考方案2】:

由于HttpSession 没有get 方法,您需要使用其中提供的一种方法来操作会话。使用getAttribute方法获取会话值。

$session.getAttribute('A')

如果您在 Struts2 中使用 FreeMarker 模板,上述方法将起作用。

在您的情况下,您没有将会话映射设置为模型。将您的 rootMap 声明更改为 Map&lt;String, Object&gt; 并将会话映射放入其中。

Map<String, Object> rootMap = new HashMap<String, Object>();
rootMap.put("session", sessionMap);

然后在模板中你可以这样称呼它:

$session['A']

【讨论】:

没有 Aleksandra,它不起作用。第 38 行未定义表达式会话 有问题的指令: ---------- ==> $session.getAttribute('A') [在第 38 行,第 32 列中【参考方案3】:

Freemarker 中的变量名区分大小写,会话存储在Session(大写)下。 所以,你的代码应该是:

<#if Session.A?exists>
    $Session.A
</#if>

或者(因为不推荐使用内置的exists

<#if Session.A??>
    $Session.A
</#if>

【讨论】:

--freemarker.core.InvalidReferenceException: Expression Session is undefined on line 39

以上是关于无法访问 freemarker 模板中的会话属性的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Freemarker 模板中访问 Spring 应用程序属性?

spring freemarker在handlerinterceptor中添加属性

Netsuite / Freemarker - 访问电子邮件模板中的交易行级别数据

Freemarker 模板从路径 WEB-INF\ftl\ 访问 Freemarker 文件

无法访问 Django 模板中的属性

在 Freemarker 模板中访问 portlet 命名空间