【问题标题】:jstl - el - read element from mapjstl - el - 从地图中读取元素
【发布时间】:2012-10-13 12:08:35
【问题描述】:

更新:代码现在在 github 中,以及重现错误的说明(在 README.md > 说明重现 jstl - el - 从地图中读取元素)。有关我的 jsp 文件的格式,请参阅我的 other question。这个我还没想通

这行得通:

<%
    HttpSession ses = (HttpSession)  request.getSession(false);
    if(ses != null) {
        HashMap<String, String> m = (HashMap<String, String>) ses.getAttribute("messages");
        if(m != null) { %>
            <%=m.get(request.getParameter("r")) %>
    <%}
    }
%>

这不是:

<c:set var="key" value="${param.r}"/>
<c:out value="${key}" /> <!-- does print what I expect -->
<%-- ${sessionScope.messages} prints nothing --%>
sess scope : ${sessionScope} <%-- prints sess scope : {}  --%>
<c:out value="${sessionScope.messages[key]}" /> <!-- nothing !? -->

为什么?

jstl-1.2.1 - 也尝试使用 1.2

relevant jsp(error_begin.jsp - 由 error_end.jsp 补充,仅包含结束 }):

<%@ page language="java" pageEncoding="UTF-8"%><!-- noway to include this ONCE -->
<%@page import="java.util.HashMap"%>
<% if(request.getAttribute("ErrorString") != null){ %>
Υπήρξε λάθος : ${requestScope.ErrorString}
<%} else { %>
<c:if test="${param.r != null}">
    <div class="success" align="center">
        <%
        HttpSession ses = (HttpSession)  request.getSession(false);
        if(ses != null){
            HashMap<String, String> m = (HashMap<String, String>) ses.getAttribute("messages");
            if(m != null){ %>
        <%=m.get(request.getParameter("r")) %>
        <%}
        }
     %><c:set var="key" value="${param.r}"></c:set>
<%--        <c:out value="${key}" /> --%>
<%--        ${sessionScope.messages[key]} --%>
<%--        ${sessionScope.messages} prints nothing --%>
        sess scope : ${sessionScope} <%-- prints {} --%>
<%--        <c:out value="${sessionScope.messages[key]}" /> --%>
<%--        <c:out value=" ${messages[param.r]}" /> --%>
    </div>
</c:if>
<c:forEach items="${messages}" var="entry">
    Key = ${entry.key}, value = ${entry.value}<br>
</c:forEach>

Web.xml 的相关部分:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">

WEB-INF/lib:

javax.servlet.jsp.jstl-1.2.1.jar
javax.servlet.jsp.jstl-api-1.2.1.jar
joda-time-2.1-javadoc.jar
joda-time-2.1.jar
logback-classic-1.0.7.jar
logback-core-1.0.7.jar
mail.jar
mysql-connector-java-5.1.22-bin.jar
slf4j-api-1.7.2-javadoc.jar
slf4j-api-1.7.2-sources.jar
slf4j-api-1.7.2.jar

【问题讨论】:

  • 您尝试过使用 ${messages[param.r]} 吗?
  • @rickz:是的,这就是我最终设置一个新变量的原因。会不会是bug?
  • 想解释为什么投反对票?这实际上是一个非常具体和准确的问题——这是怎么回事?
  • ${sessionScope} 说什么?还有${sessionScope.messages}?请注意,您不一定需要为此使用&lt;c:out&gt;,模板文本中的 EL 也可以正常工作(如果没有,您会遇到严重的环境问题)。
  • @BalusC : 编辑了问题:)

标签: jsp jstl tomcat7 el servlet-3.0


【解决方案1】:

您应该在您的 JSP 页面中包含 &lt;%@ page session="true" %&gt; 指令。

JSP 中页面指令的 session 属性默认为 true,但在站点的全局位置可能已设置为 false。

如果 session 属性的值为 true,那么 session 对象指的是当前或新的 session,因为客户端必须在 HTTP session 中才能在服务器上运行 JSP 页面。如果将 session 对象的值设置为 false,则不能在 JSP 页面中使用 scope="session" 的 session 对象或元素。

见:

http://www.roseindia.net/jsp/SessionAttribute.shtml

http://www.tutorialspoint.com/jsp/page_directive.htm

Why set a JSP page session = "false" directive?

Problem with session attributes in JSP EL using Spring MVC

更新:

来自 JSP 2.2 规范:

页面指令 - 会话属性:

表示页面需要参与 (HTTP) 会话。

如果为真,那么名为 session 的隐式脚本语言变量 类型 javax.servlet.http.HttpSession 引用当前/新会话 页面。

如果为 false,则页面不参与会话;会议 隐式变量不可用,并且在 JSP 页面的正文是非法的,将导致致命 翻译错误。

默认为真。

【讨论】:

  • 你在我评论时编辑了 :D ---> 你能解释一下为什么 scriptlet 代码中的会话可用 吗?如果我将session="true" 放在所有需要为真的页面上并且用户会话超时 - 我在这些页面上有过滤器检查是否request.getSession(false) == null - jsps 会在过滤器运行之前创建一个会话(所以request.getSession 不会为空)? (除此之外 - 不要阅读roseindia - 阻止它 - 非常糟糕的代码)
  • 对于您评论的第一部分:如规范中所述,当设置为 false 时,名为 session 的隐式脚本语言变量不可用。这并不意味着您不能在 scriptlet 中使用 request.getSession() 访问会话。所以,如果会话属性为假: ${messages} \\Returns null ${sessionScope.messages} \\Returns null \\抛出异常:找不到变量 session \\工作正常 - 返回会话属性
  • 谢谢 - session="true" 的问题是在没有会话时创建会话 - 你知道这是在过滤器运行之前还是之后完成的(本质上这是我的第二个问题)?跨度>
  • 对于第二部分,我不知道过滤器指令的执行顺序,但我认为使用 request.getSession() 方法无论如何都会创建一个会话(如果还没有会话)。跨度>
  • 至于roseindia链接,我不正常使用,但它为会话属性的情况提供了一个相当容易理解的示例,即使代码很糟糕;)
猜你喜欢
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
相关资源
最近更新 更多