jsp - 什么时候在 JSP 中设置请求范围的变量合适?

标签 jsp jstl scope lexical-scope dynamic-scope

根据我的经验,很少/从不需要设置 scope="request"在 EL 变量上。

例如,我有一个页面,给定 item参数,根据其属性构造特定于该项目的 URL。此页面包含在需要呈现项目链接的任何页面中。

(A) 使用请求范围的变量

itemLink.jsp

<%-- Accepts a parameter named 'item' --%>
<c:set var="urlTemplate" value="${param['item'].urlTemplate}" />
<c:choose>
  <c:when test="${empty urlTemplate}">
    <c:set var="itemUrl" scope="request" value="/missingProductUrl.jsp"/>
  </c:when>
  <c:otherwise>
    <c:url var="itemUrl" scope="request" value="${urlTemplate}">
      <c:param name="id" value="${param['item'].id}"/>
    </c:url>
  </c:otherwise>
</c:choose>

其他页面.jsp
<jsp:include page="itemLink.jsp">
  <jsp:param name="item" value="${currentItem}"/>
</jsp:include>

<%-- 'itemUrl' has request scope --%>
<a href="${itemUrl}">Item Link</a>

(B) 没有请求范围的变量

itemLink.jsp
<%-- Accepts a parameter named 'item' --%>
<c:set var="urlTemplate" value="${param['item'].urlTemplate}" />
<c:choose>
  <c:when test="${empty urlTemplate}">
    <c:set var="itemUrl" value="/missingProductUrl.jsp"/>
  </c:when>
  <c:otherwise>
    <c:url var="itemUrl" value="${urlTemplate}">
      <c:param name="id" value="${param['item'].id}"/>
    </c:url>
  </c:otherwise>
</c:choose>

<c:out value="${itemUrl}"/>

其他页面.jsp
<c:set var="itemUrl">
  <jsp:include page="itemLink.jsp">
    <jsp:param name="item" value="${currentItem}"/>
  </jsp:include>
</c:set>

<%-- 'itemUrl' has page scope --%>
<a href="${itemUrl}">Item Link</a>

有什么理由使用 (A) (B) ?我的回答是否定的,理由如下:
  • (A) ,您需要记住,在同一请求期间处理的任何其他页面都会看到 itemUrl ,因此您应该避免名称冲突。它还使得跟踪 EL 变量的来源更加困难,因为除了搜索在同一请求期间处理的所有页面之外,无法找到设置请求范围变量的位置。
  • (B) ,这都不是问题,因为变量只有页面范围。

  • 编辑:

    也许有比 更好的解决方案(B) :

    (C) 使用静态包含

    itemLink.jspf
    <%-- Accepts a parameter named 'item' --%>
    <c:set var="urlTemplate" value="${param['item'].urlTemplate}" />
    <c:choose>
      <c:when test="${empty urlTemplate}">
        <c:set var="itemUrl" value="/missingProductUrl.jsp"/>
      </c:when>
      <c:otherwise>
        <c:url var="itemUrl" value="${urlTemplate}">
          <c:param name="id" value="${param['item'].id}"/>
        </c:url>
      </c:otherwise>
    </c:choose>
    

    其他页面.jsp
    <c:set var="item" value="${currentItem}"/>
    <%@ include page="itemLink.jsp" %>
    
    <%-- 'itemUrl' has page scope --%>
    <a href="${itemUrl}">Item Link</a>
    

    仍然是没有选择的情况, (B) 也不是 (C) , 需要使用请求范围的变量。是否有使用我错过的请求范围的原因?

    最佳答案

    您介绍的这一部分

    
    <c:set var="itemUrl">
    <jsp:include page="itemLink.jsp">
    <jsp:param name="item" value="${currentItem}"/>
    </jsp:include>
    </c:set>

    仅当 itemLink.jsp 只有 itemUrl 的值而没有其他值时才有效(没有额外的 html 内容)但几乎不是这种情况。

    考虑这样一种情况,您在 one.jsp 的请求范围内有一个 Car 对象,并且此页面中的链接将您带到需要同一个 Car 对象的 two.jsp。

    然后
    
    <c:set var="myCar" value="${requestScope.car}" scope="request"/> 
    

    会做的工作。这对于方法(B)是不可能的。

    更新:
    至于为什么方法(B)不可能:在您的代码段中 jsp:include 包括 JSP 的响应(文本),然后将其设置为 itemUrl。如果您需要将复杂对象(非文本对象,如 Car 或 ArrayList )分配给请求范围属性,该怎么办? JSP 响应通常是 html 文本。

    只是提出一个替代方案,为什么不这样渲染?
    
    
    <%-- Accepts a parameter named 'item' --%>
    <c:set var="urlTemplate" value="${param['item'].urlTemplate}" />
    <c:choose>
    <c:when test="${empty urlTemplate}">
    <a href value="/missingProductUrl.jsp"/>
    </c:when>
    <c:otherwise>
    <c:url var="itemUrl" scope="request" value="${urlTemplate}">
    <c:param name="id" value="${param['item'].id}"/>
    </c:url>
    <c:out value="${itemUrl}"/>
    </c:otherwise>
    </c:choose>
    
    

    <jsp:include page="itemLink.jsp">
    <jsp:param name="item" value="${currentItem}"/>
    </jsp:include>

    总而言之,我几乎没有遇到过 c:set 的情况。需要。通常,任何范围属性的设置都是由 servlet/ Controller 完成的。 JSP 只会获得一个作用域属性并显示它。如果 JSP 正在设置范围属性,那么维护将非常困难。最好限制使用c:set仅设置页面范围的属性。

    关于jsp - 什么时候在 JSP 中设置请求范围的变量合适?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7587046/

    相关文章:

    java - 有没有办法对多个变量使用单个注释?

    java - 将 "Localhost2"指向 tomcat 中的新文件夹

    java - Spring MVC在jsp页面导入css和js

    eclipse - Eclipse Indigo 上的编译错误 : javax. servlet.jsp.JspException,javax.servlet.jsp.PageContext 无法解析为类型

    function - 支持词法范围 ScriptBlock 参数(例如Where-Object)

    javascript - 为什么 const 在 JavaScript 中的某些 for 循环中有效?

    java - 类无法解析为类型

    java - Spring MVC 配置 url-pattern

    java - 使用 JSTL 访问 Struts2 操作

    java - IntelliJ 中的 JSTL 在 JSP 中给出错误