在 JSP 小脚本中对 select 框项目进行排序

Sort select box items in a JSP scriptlet

我正在使用旧的 Tomcat 服务器,提供它的软件开发人员不再支持它。 web.xml 没有告诉我我正在使用的 JSP 是什么版本,但是所有 .class 文件都是 Java 1.5.

我有一位客户很不高兴,因为系统有 html 个由 Java 自动填充的框,它会直接填充 [=] 的(无序)结果34=]数据库查询。我试图将一些代码偷偷放入 JSP 中,以便选择器在填充字段列表之前对其进行排序,但它不起作用,我不明白为什么。

(删节)相关代码:

<%@ page import="src.explorer.ObjectStateFactory"%>
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>


<jsp:useBean id="ExplorerViewContext" scope="session" type="src.explorer.ExplorerViewContext"/>

...

<c:forEach var="nc" items="${ExplorerViewContext.networkControllers}">
    <c:choose>
        <c:when test="${nc.name == ExplorerViewContext.networkControllerSelection.name}">
            <option value="<c:out value="${selectAction}${nc.objectKey}"/>" selected><c:out value="${nc.name}"/></option>
        </c:when>
        <c:otherwise>
            <option value="<c:out value="${selectAction}${nc.objectKey}"/>"><c:out value="${nc.name}"/></option>
        </c:otherwise>
    </c:choose>
</c:forEach>    
        </select>

我添加的相关代码:

 <%@ page import="src.explorer.ObjectStateFactory"%>
    <%@ page import="java.util.*"%>
    <%@ page language="java" %>
    <%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>


    <jsp:useBean id="ExplorerViewContext" scope="session" type="src.explorer.ExplorerViewContext"/>

    ...

   <%
    final Comparator<src.explorer.XmldbObjectState> NC_ORDER = new Comparator<src.explorer.XmldbObjectState>(){
        public int compare(src.explorer.XmldbObjectState  nc1, src.explorer.XmldbObjectState nc2){
            return nc1.getName().compareTo(nc2.getName());
        }
    };

    List myList = ExplorerViewContext.getNetworkControllers();
    java.util.Collections.sort(myList,NC_ORDER);
    %>
    <c:forEach var="nc" items="${myList}">
        <c:choose>
            <c:when test="${nc.name == ExplorerViewContext.networkControllerSelection.name}">
                <option value="<c:out value="${selectAction}${nc.objectKey}"/>" selected><c:out value="${nc.name}"/></option>
            </c:when>
            <c:otherwise>
                <option value="<c:out value="${selectAction}${nc.objectKey}"/>"><c:out value="${nc.name}"/></option>
            </c:otherwise>
        </c:choose>
    </c:forEach>    
            </select>

基本上,我试图获取列表并在它被发送到 HTML 之前对其进行排序。问题是,myList 总是空着,我不明白为什么。我猜原始代码中的 ExplorerViewContext.networkControllers 是在 ExplorerViewContext 的实例上调用 getNetwrokControllers() 方法,是吗?为什么我不能在 scriptlet 中做同样的事情并在提供之前稍微重新格式化输出?

您不应将 Scriptlet 代码添加到已仅使用 JSTL 的代码中。更好的做法是编辑 bean class src.explorer.ExplorerViewContext 以自动为您对内部进行排序。

无论如何,${myList} 在 JSTL 中什么都不做的原因是在 scriptlet 中创建的变量(即在 <%%> 之间)对于 JSTL 不存在。要使变量存在于 JSTL 中,您必须在 JSTL 中创建它,或在页面上下文中设置它,或者它必须在会话或请求中。通常你把它放在会话中或在 servlet 中请求。

在这种情况下,您的列表在 bean 中,因此最好只编辑 bean class 来对列表进行排序。但是您可以在此处将变量设置到页面上下文中,以便 JSTL 可以使用它:

<%
...
List myList = ExplorerViewContext.getNetworkControllers();
java.util.Collections.sort(myList,NC_ORDER);
pageContext.setAttribute("myList", myList); //set in pageContext so JSTL can see it
%>
<c:forEach var="nc" items="${myList}">

就代码而言 "legacy" 向其中添加 scriptlet 会使它更加传统。事实上,这段代码比您尝试添加的修改更现代。但只是略微如此,因为使用 <jsp:useBean> 是使用 bean 的过时方法。