【问题标题】:Not able to access session attributes in freemarker templates无法访问 freemarker 模板中的会话属性
【发布时间】: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;

【问题讨论】:

    标签: java email struts2 freemarker


    【解决方案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
    猜你喜欢
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 2013-06-18
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    相关资源
    最近更新 更多