【问题标题】:JSTL loop in JSP for nested unrodered listsJSP 中的 JSTL 循环用于嵌套的未遍历列表
【发布时间】:2014-01-08 12:05:19
【问题描述】:

MVC - servlet 将请求转发给 JSP。 在 servlet 中,我创建了类别列表 (java.util.List),将此列表附加到 servlet 上下文,并将请求转发到 JSP 页面:

public class Category{
       private Integer id;
       private String name;
       private Category parentCategory;
       ...
       //getters and setters
    }

该类表示类别/子类别(如果 parentCategory 字段为空,则为顶级类别)。 具有相同父类别的类别是其子类别,它们在 JSP 中映射到嵌套的无序列表。 示例:结果应该类似于下一个 HTML 代码:

<ul class="droprightMenu">  
            <li><a href="#">Category 1</a>
                <ul class="droprightMenu">
                    <li><a href="#">Category 1.1</a></li>
                    <li><a href="#">Category 1.2</a></li>
                    <li><a href="#">Category 1.3</a></li>
                          <ul class="droprightMenu">
                                <li><a href="#">Category 1.3.1</a></li>
                                <li><a href="#">Category 1.3.2</a></li>
                                <li><a href="#">Category 1.3.3</a></li>
                                <li><a href="#">Category 1.3.4</a></li>
                          </ul> 
                    <li><a href="#">Category 1.4</a></li>
                </ul>
            </li>
            <li><a href="#">Category 2</a></li>
            <li><a href="#">Category 3</a></li>
                <ul class="droprightMenu">
                    <li><a href="#">Category 3.1</a></li>
                    <li><a href="#">Category 3.2</a></li>
                          <ul class="droprightMenu">
                                <li><a href="#">Category 3.2.1</a></li>
                                <li><a href="#">Category 3.2.2</a></li>
                          </ul> 
                    <li><a href="#">Category 3.3</a></li>
                    <li><a href="#">Category 3.4</a></li>
                </ul>
            <li><a href="#">Category 4</a></li>
    </ul>

我不知道如何在 JSP 中循环遍历这个列表。它可能应该通过一些不同的 JSTL 循环或 JSP 脚本的组合来完成,也许是一些递归。 感谢任何帮助。

【问题讨论】:

    标签: java jsp servlets jstl


    【解决方案1】:

    如果您不知道类别树的深度,您仍然可以使用递归生成菜单。

    使用与上一个响应中的Loc相同的Model,你必须定义一个名为menuitem.jsp的jsp页面,它将被递归调用:

    <li>
       <a href="#">${menuitem.name}</a>
       <c:if test="${fn:length(menuitem.subCategories) gt 0}">
          <ul class="droprightMenu">
             <c:forEach var="menuitem" items="${menuitem.subCategories}">
               <c:set var="menuitem" value="${menuitem}" scope="request" />
               <jsp:include page="menuitem.jsp" />
             </c:forEach>
          </ul>
       </c:if>
    </li>
    

    在我们的 JSP 主页面中,初始化变量 menuitem 并包含该 jsp。

    <c:set var="menuitem" value="${rootMenu}" scope="request" />
    <jsp:include page="menuitem.jsp" />
    

    【讨论】:

    • 感谢您的回复。我不知道如何递归地实现这个,所以我将类别深度限制为三个(见我的回答)。但现在,我会考虑你的选择。
    【解决方案2】:

    您需要像这样填充您的模型:

    public class Category{
       private Integer id;
       private String name;
       private Category parentCategory;
    
       private List<Category> subCategories;
    
       ...
       //getters and setters
    }
    

    在 Servlet 中,您需要具有类别 LEVEL 1 的 LIST(Parent 为 NULL)。

    List<Category> rootCategories = getAllCategoriesLevel1();
    request.setAttribute("rootCategories",  rootCategories );
    

    在 JSP 中(需要 3 个循环或 4,5 个循环)

    <c:forEach items="${rootCategories}" var="categoryLevel1">
    
        // ...
    
        <c:forEach items="${categoryLevel1.subCategories}" var="categoryLevel2">
    
            // ...
    
            <c:forEach items="${categoryLevel2.subCategories}" var="categoryLevel3">
    
                // ...  
    
            </c:forEach>
    
            // ...
    
        </c:forEach>
    
        // ...
    
    </c:forEach>
    

    【讨论】:

    • 您可以使用 来包装 c:forEach 语句。你必须限制你的最高水平。假设您的最高级别为 5,您在 JSP 中有 5 个循环。因为你已经使用了
    • 好的,假设类别中有一个(或一组)子类别列表。但是,同样,我不知道子类别的确切级别有多深,有多少 foreach 嵌套循环。那么,应该如何看待一些涵盖所有子类别的 JSTL 循环模式,而不仅仅是直到特定级别?
    【解决方案3】:
    <c:forEach var="rootCategory" items="${allCategories}" varStatus="rootCategoryLoop">
        <c:if test="${rootCategory.rootCategoryId eq product.rootCategoryId}">
            <c:forEach var="category" items="${rootCategory.categories}" varStatus="categoryLoop">
                <c:if test="${category.categoryId eq product.categoryId}">
                    <c:forEach var="subCategory" items="${category.subCategories}" varStatus="subCategoryLoop">
                        <c:choose>
                            <c:when test="${subCategory.subCategoryId eq product.subCategoryId}">
                                <div>${subCategory.subCategoryName}</option>
                            </c:when>
                            <c:otherwise>
                                <div}">${subCategory.subCategoryName}</option>
                            </c:otherwise>
                        </c:choose>  
                    </c:forEach>
                </c:if> 
            </c:forEach>
        </c:if>
    </c:forEach>
    

    【讨论】:

      【解决方案4】:

      我的子类别级别有限 - 到 3 级。 所以,这是servlet中的代码:

      // findAll() - returns all categories in database, as a list
      List<Category> categories = categoryDao.findAll(); 
      ServletContext servletContext = getServletContext();
      servletContext.setAttribute("categories", categories); 
      

      这些是 JSP 页面中的循环,我在哪里从列表中提取数据并生成 html 标记:

              <li><a href="#">Categories</a>
                  <ul class="droprightMenu">
                      <li><a href="#">All</a>
                          <ul class="droprightMenu">
      
                              <!-- first loop, extracting categories level 1  -->
                              <c:forEach items="${categories }" var="catLevel1">
      
                                  <c:if test="${catLevel1.getParentCategory()==null }">
                                      <li><a href="#">${catLevel1.getName() }</a> 
      
                                      <!-- second loop, extracting categories level 2  -->
                                          <ul class="droprightMenu">
                                              <c:forEach items="${categories }" var="catLevel2">
      
                                                  <c:if test="${catLevel2.getParentCategory().getId()==catLevel1.getId() }">
                                                      <li><a href="#">${catLevel2.getName() }</a> 
      
                                                      <!-- third loop, categories level 3  -->
                                                          <ul class="droprightMenu">
                                                              <c:forEach items="${categories }" var="catLevel3">
      
                                                                  <c:if test="${catLevel3.getParentCategory().getId()==catLevel2.getId() }">
                                                                      <li><a href="#">${catLevel3.getName() }</a></li>
                                                                  </c:if>
      
                                                              </c:forEach>
                                                          </ul></li>
                                                  </c:if>
      
                                              </c:forEach>
                                          </ul></li>
                                  </c:if>
                              </c:forEach>
      
                          </ul></li>
                  </ul></li>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-06-22
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        • 2014-05-11
        相关资源
        最近更新 更多