【问题标题】:Session attribute not responding inside EL expression会话属性在 EL 表达式中没有响应
【发布时间】:2015-07-12 00:04:46
【问题描述】:

我知道这可能看起来像 duplicate question。不幸的是,没有可接受的有效答案。甚至 OP 也面临着不同的问题,而不是它所说的问题。

POJO 类如下:

private boolean admin = false;
private boolean isNormal = false; 

public void setAdmin(boolean admin) {
    this.admin = admin;
}
public boolean getAdmin() {
    return admin;
}
public void setIsNormal(boolean isNormal) {
    this.isNormal= isNormal;
}
public boolean getIsNormal() {
    return isNormal;
}

// In this class I have many boolean flags like above two. I need to access those in the my JSP

Servlet 代码如下:

System.out.println(responseHeader.getAdmin()); //printed 'True'
session.setAttribute("header", responseHeader);
request.getRequestDispatcher("/DashBoard/Shipper").forward(request, response);

JSP 下面的代码:

<%StaticHeader sh = (StaticHeader)session.getAttribute("header");//getting the StaticHeader Object from the session
pageContext.setAttribute("headerFromSession",sh); // set the StaticHeader Object again into PageContext (may be unnecessary): 
%>

以下所有场景都不起作用,我也没有遇到任何异常。

1.) <c:if test="${headerFromSession.getAdmin()}"> //seems to be standard, formal way. But it didn't work
2.) <c:if test="${headerFromSession.Admin}"> // Is this legal? I mean, 'admin' is a private variable. 
3.) <c:if test="${headerFromSession.ADMIN}">
4.) <c:if test="${headerFromSession[Admin]}">
5.) <c:if test="${headerFromSession[ADMIN]}">
6.) <c:if test="${headerFromSession}"> //This seems like totally not correct. Because I have many boolean flages which I have already set to the StaticHeader Object

【问题讨论】:

  • 能否请您出示您的 servlet 代码?这将有助于更好地理解
  • 好的,我假设header 是StaticHeader 的一种类型,那么您如何设置SHIPPER 的SHIPPER 的属性?
  • 如果header 已经正确设置为更宽的范围,那么为什么需要再次将其设置为更窄的范围?此外,使用 JSTL 完全排除 Scriptlets。
  • 是的,为什么不只使用&lt;c:if test="${header}"&gt; 而不是&lt;c:if test="${header.ADMIN}"&gt;,因为header 还包含布尔值。
  • @Tiny 我认为会话变量不能在 EL 中直接访问。所以我把它放在PageContext中。可能是额外的工作,但我面临的问题与此无关。不是吗?

标签: java jsp el jsp-tags


【解决方案1】:

这里有几个问题。

  1. 您的 bean(或您想称其为“POJO”)不遵循 Javabeans specification 和 boolean properties。特别是boolean getter 的形式为isPropertyName() 而不是getPropertyName()。

    相应地修复它:

    private boolean admin = false;
    private boolean normal = false; 
    
    public void setAdmin(boolean admin) {
        this.admin = admin;
    }
    
    public boolean isAdmin() {
        return admin;
    }
    
    public void setNormal(boolean normal) {
        this.normal = normal;
    }
    
    public boolean isNormal() {
        return normal;
    }
    

  2. 您正在为引用HTTP request header 的reserved EL variable 的名称设置会话属性。简单地说:${header} 变量已经被保留。这应该用于访问 EL 中的 HTTP 请求标头,例如 ${header['User-Agent']}。

    给它一个不同的名字:

    session.setAttribute("staticHeader", staticHeader);
    

    请注意,为了清楚起见,我还重命名了 Java 变量,因为这绝对不代表“response header”。否则只会让阅读此代码的其他人感到困惑,并且一旦您对 Java Servlet 和 HTTP 更加流利,以后可能还会让您自己感到困惑(我只是仍然想知道“静态标头”在这种情况下到底是什么意思,作为有根据的猜测我认为您过于复杂了“用户角色”或“用户组”,但唉)。

    这样它就可以在 EL 中以 ${staticHeader} 的形式使用,并且您不需要弄乱那种丑陋的 scriptlet 变通方法,即在页面上下文中以不同的名称放置副本。


  3. 您访问 bean 属性的尝试不符合 EL specification。您应该使用${bean.propertyName} 的形式,而不是${bean.PropertyName},当然也不能使用其他形式。如果您确实需要大括号表示法(因为它是作为另一个变量提供的),那么您仍然需要确保字符串值是 propertyName,就像在 ${bean['propertyName']} 中一样。

    所以,应该这样做:

    <c:if test="${staticHeader.admin}">
    

    请注意,这不会访问private 字段,而是调用isAdmin() getter 方法。此外,private 字段的存在与 EL 无关,您甚至可以将其完全删除。


我强烈建议您(以及该问题的所有评论者)暂停一下您当前正在工作的 JSP/Servlet 项目,并阅读一本理智的 JSP/Servlet 书籍/教程。以上都在里面。

【讨论】:

  • 天啊!由“BalusC”回答。太棒了!...感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 2018-06-05
  • 2013-04-15
  • 2020-02-13
  • 2023-03-26
相关资源
最近更新 更多