java - 渲染父 subview 导致StackOverflow异常

标签 java jsp recursion jstl

我无法在jsp页面中呈现嵌套的父子树结构。由于stackover flow错误导致

 <code><jsp:include page=""/></code>

我的数据库:

 Id ||  Name  ||  Parentid  ||
 1  ||  animal||  0         ||  
 2  ||  Dog   ||  1         ||    etc.

模型类:

public class Node {
    private int id;
    private String name;
    private int parentId;
    private List<Node> children;

    public Node() {
    }

    public Node(String name, int parentId, List<Node> children) {
        this.name = name;
        this.parentId = parentId;
        this.children = children;
    }

DAO 类:

 @Override
    public List<Node> nodelist() {

         String sql = "select * from tree";
      List<Node> listNode = jdbcTemplate.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
               Node node = new Node();
                    node.setId(rs.getInt("id"));
                node.setName(rs.getString("name"));
                node.setParentId(rs.getInt("parent_id"));

                return node;


            }

        });

        return listNode;
    }

在 Controller 中,我绑定(bind)对象如下:

List<Node> rootNodes;

@Autowired
    TreeDao treeDao;


    @RequestMapping(value = "/node", method = RequestMethod.GET)
    public ModelAndView getallnodes(ModelAndView model) throws IOException {

        //menuObj = menuDao.listCategory();
        List<Node> listnode = treeDao.nodelist();

        getInfiniteTree(listnode);
        model.addObject("rootNodes",rootNodes);
        model.setViewName("tree");

        return model;
    }

    public List<Node> getInfiniteTree(List<Node> nodes) {
        return findRootNodes(nodes);
    }

    private List<Node> findRootNodes(List<Node> nodes) {
        rootNodes = new ArrayList<Node>();
        for (Node node : nodes) {
            if (node.getParentId() == 0) {
                rootNodes.add(node);
                findChildNodes(node, nodes);
            }
        }



System.out.println("rootnodes "+rootNodes);


    Gson gson = new Gson();
    System.out.println(gson.toJson(rootNodes));
     //I got the correct json format data here.
        //Collections.sort(rootNodes);
        return rootNodes;
    }



    private  void findChildNodes(Node parentNode, List<Node> nodes) {
        List<Node> children = new ArrayList<Node>();
        parentNode.setChildren(children);
        for (Node node : nodes) {
            if (node.getParentId() == parentNode.getId()) {
                children.add(node);
                findChildNodes(node, nodes);
            }
        }

        //Collections.sort(children);
    }

在另一个java swing项目中,我测试了类似的代码并得到了以下字符串结果:

nodes [Node{id=1, name=供应链部, parentId=0, sort=3, children=[Node{id=5, name=物流部, parentId=1, sort=1, children=[]}, Node{id=6, name=采购部, parentId=1, sort=2, children=[]}]}, Node{id=2, name=技术部, parentId=0, sort=1, children=[Node{id=7, name=开发部, parentId=2, sort=2, children=[Node{id=12, name=后端部, parentId=7, sort=2, children=[]}, Node{id=13, name=前端部, parentId=7, sort=2, children=[Node{id=14, name=diee, parentId=13, sort=2, children=[]}, Node{id=15, name=diee, parentId=13, sort=2, children=[]}]}]}, Node{id=8, name=测试部, parentId=2, sort=1, children=[]}, Node{id=9, name=运维部, parentId=2, sort=3, children=[]}]}, Node{id=3, name=行政部, parentId=0, sort=2, children=[Node{id=10, name=招聘部, parentId=3, sort=1, children=[]}, Node{id=11, name=人事部, parentId=3, sort=2, children=[]}]}, Node{id=4, name=公关部, parentId=0, sort=4, children=[]}]

问题是我无法使用jsp递归显示它,我尝试了下面的代码:

树.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>

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

menuitem.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<ul>
    <c:forEach var ="menuitems" items="${menuitem}">
        <li><a href="#">${menuitems.name}</a></li>
        <ul>
   <c:if test="${fn:length(menuitems.children) gt 0}">
      <li class="droprightMenu">
          <c:out value="Has children"></c:out>
         <c:forEach var="menuitemc" items="${menuitems.children}">
           <c:set var="menuitem" value="${menuitemc}" scope="request" />
           <%--<jsp:include page="menuitem.jsp" />--%>
         </c:forEach>
      </li>
   </c:if>
      </ul>
      </c:forEach>
</ul>

它不包括通过无限子级的页面,并且由于我是 JSP 递归的新手,请忽略我的错误。我在这里呆了几天。 异常(exception):

Don't know how to iterate over supplied "items" in &lt;forEach&gt;
org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/views/menuitem.jsp at line 14

11: 
12: 
13: <ul>
14:     <c:forEach var ="menuitems" items="${menuitem}">
15:         <li><a href="#">${menuitems.name}</a></li>
16:         <ul>
17:    <c:if test="${fn:length(menuitems.children) gt 0}">

最佳答案

menuitem.jsp

 <c:forEach var="menuitem" items="${menuitem.children}">
    <li><a href="#" id="${menuitem.id}"><i class="fa fa-circle-o"></i>  <span>${menuitem.name} </span></a></li>
    <c:set var="menuitem" value="${menuitem}" scope="request" />
    <jsp:include page="/WEB-INF/views/menuitem.jsp" />
 </c:forEach>

我认为问题就出在这里。尝试将 var="menuitem" 重命名为 var="childmenuitem。 我相信您当前不断将相同的对象传递到子菜单,从而导致无限循环。

关于java - 渲染父 subview 导致StackOverflow异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46808718/

相关文章:

java - 当我们在不同的命令提示符下发出 java 命令时,会创建多少个 JVM 实例?

java - Action 监听器太快了,我进入下一个菜单

java - SQL 异常,未请求生成的键

java - 在 JSP 中保存单选按钮

java - 递归方法要求从 1 到 10 的整数

java - Java 文件中的编码问题

java - 使用java刷新文件系统

java - <html :select> multiple values how to get values into Action form

node.js - Node.js 中的分阶段执行递归循环

c - 递归:在其位置反转字符串