例如,我有一个页面,给定一个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>
otherPage.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}"/>
otherPage.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>
otherPage.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只会获得一个scoped属性并显示它.如果JSP设置范围属性,则维护起来非常困难.最好将c:set的使用限制为仅设置页面范围属性.