无法在Freemarker模板中访问会话属性

3

我有一个行动类,设置了会话属性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。
以下是额外的代码,在Action类中,我向会话对象添加了值:
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);

Session map被声明为

 private Map<String, Object> sessionMap;
3个回答

4

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

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

或者(由于exists内置函数已被弃用)
<#if Session.A??>
    ${Session.A}
</#if>

freemarker.core.InvalidReferenceException: 第39行表达式中的Session未定义。 - Kiran Badi

1

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

${session.getAttribute('A')}

如果您在Struts2中使用FreeMarker模板,上述方法将起作用。
在您的情况下,您没有将会话映射设置为模型。将rootMap声明更改为Map<String,Object>并将会话映射放入其中。
Map<String, Object> rootMap = new HashMap<String, Object>();
rootMap.put("session", sessionMap);

然后在模板中,您可以这样调用它:
${session['A']}

不好意思,Aleksandra,它没有起作用。第38行出现了未定义的表达式session。有问题的指令是:---------- ==> ${session.getAttribute('A')} [位于第38行,第32列] - Kiran Badi

0
在 freemarker 中没有会话对象,你应该做类似这样的事情。
<#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());

让我确认一下,稍后回复。 - Kiran Badi
它不起作用,我知道会话中有值,在调用freemarker模板之前,我调用jsp并输出会话值,在那里我可以看到值,${A};${B};<s:property value="#session['A']"/>和<s:property value="#session['B']"/>,但是在freemarker中相同的<s:property>标签不起作用。可能需要在freemarker上启用调试。 - Kiran Badi
我的结果类型不是FTL,而是jsp,我发送电子邮件,该电子邮件模板是FTL。我将会话值存储在值堆栈中,然后想要在FTL模板中访问这些值。我有一个触发电子邮件类的操作类,在该电子邮件类中,我加载FTL模板并进行所需的处理,一旦发送电子邮件,一切都正常工作,只是在FTL模板中我无法获取值。但是在配置为jsp结果类型时,值是存在的。 - Kiran Badi
发布你正在做的代码,代码应该是一个自包含的示例。你能在那里访问值堆栈吗? - Roman C
添加了相关的代码部分 Roman,请看看你能否想到什么,我所需要的就是从Freemarker中访问值栈数据。 - Kiran Badi
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接