JSTL <c:when> 标签中的结果始终相同

Always same result in JSTL <c:when> tag

我的 login.jsp 页面出现了这个奇怪的问题。让我们看一下这里的 jsp 代码的一部分:

<%
  String userName = "";
  String password = "";
  boolean login;

  //mysql stuffs are in here

if(resultSet.next()) {
  login = true;
  out.println("It is true.");
} else {
  login = false;
  out.println("It is false.");
%>

当我使用正确的 username/password 登录时,我在页面顶部得到 It is true 输出,并且我得到 It is false 输出,其中包含一些错误的登录信息。

到目前为止一切正常。现在,让我们看看这里的 html 内容:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <c:choose>
      <c:when test="${login}">
        <div class="container">
          <!-- Page content in here with success -->
        </div>
      </c:when>

      <c:otherwise>
        <div class="container">
          <!-- Page content in here with error -->
        </div>
      </c:otherwise>
    <c:choose>
  </body>
</html>

现在,无论输入正确或错误的搜索信息,我总是得到相同的 HTML 页面内容,但我总是从页面顶部的布尔值得到正确的输出。有人可以告诉我我在这里缺少什么吗?

将 scriptlet (<%...%>) 与 JSTL 混合使用违背了使用 JSTL 的目的。此外,在 JSTL 中无法使用 ${} 访问在 scriptlet 中设置的变量。 JSTL 旨在取代 <%...%> 东西并使用 MVC 方法,在该方法中您使用 Servlet 作为控制器。您在 <%...%> 中拥有的东西应该在一个设置请求属性并转发到包含 JSTL 的 jsp 的 Servlet 中。然后JSTL可以用${login}.

读取请求属性

因此,在 login.java 中,您的 servlet,在设置布尔值的代码之后(在您的 doPost 方法中):

request.setAttribute("login", login);
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
return;

您可以将 JSP 放在 WEB-INF 下,以防止任何用户直接访问它。相反,您会让它们转到登录 servlet 的 URL,它将控制对 JSP 的访问,因此它被称为 "controller."(您可以看到 servlets info page了解更多信息。)

您还需要设置 no-cache headers 以防止缓存受登录保护的页面,因为这些页面被缓存会带来安全风险,因为任何人都可以通过物理方式访问机器以查看用户在注销后登录时看到的内容。

您需要创建一个 "page scope" 变量才能在 ${ ... }

之间使用它

将顶部的示例更改为:

if(resultSet.next()) {
    pageContext.setAttribute("login", "true");
    out.println("It is true.");
} else {
    pageContext.setAttribute("login", "false");
    out.println("It is false.");
}

它应该一切正常。

注意:这假定您在 <% ... %> 中的其他任何地方都不需要 "boolean login" 如果是这种情况,您也可以删除 "boolean login" 行。如果您确实需要它,则保留它并添加 "login = true" 和 "login = false" 行,但您仍然需要 pageContext.setAttribute 语句。