【发布时间】:2018-09-01 11:26:40
【问题描述】:
我在尝试将对象另存为 Json 时发现了一些关于无限循环的类似线程,但其中大多数是关于 java + jpa 的,这些解决方案对我不起作用。我想创建一些数据的树结构。有类ProjectNode得到了
private ArrayList<ProjectNode> children;
字段。我很确定这门课程是问题所在,但它是这个结构中的主要领域,我不能忽视它。我已经测试过,我可以将具有列表的对象转换为没有子节点的节点,但是如果任何子节点在下面的代码中有另一个子节点,则不能:
public class ProjectNode implements Comparable<ProjectNode>{
private String parent;
private String nodeName;
private String nodeHref;
private boolean hasChild;
private int td;
private ArrayList<ProjectNode> children;
public ProjectNode() {
super();
// TODO Auto-generated constructor stub
}
+ 获取器和设置器
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(parser.getProjectFactory().get(12));
parser.getProjectFactory() 返回ParentNodes 的列表(parent=null),我想转换 12 个元素,因为存在节点有孩子而这个孩子有孩子的情况。导致此错误:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"])
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:734)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
编辑: Parser - 从 cacti 解析项目/主机列表:
public List<ProjectNode> getProjectFactory() throws FailingHttpStatusCodeException, MalformedURLException, IOException {
FileWriter fstream = new FileWriter("graphMap.txt");
BufferedWriter out = new BufferedWriter(fstream);
String [] hostInfo = null;
HtmlTableCell cel= (HtmlTableCell) page.getHtmlPage().getByXPath("/html/body/table/tbody/tr[5]/td[1]").get(0);
System.out.println(cel.getChildElementCount());
List<HtmlDivision> divs = cel.getByXPath(".//div");
System.out.println(divs.size());
//checks if list of host has been added to the project
ProjectTree projectTree = new ProjectTree();
Map<Integer,String> suppMap = new HashMap<Integer,String>();
for(HtmlDivision div : divs) {
List<DomNode> td = div.getByXPath(".//table/tbody/tr/td");
if(td.size()>2) {
ProjectNode pn = new ProjectNode(getNameSrc(td).split("@")[0],getNameSrc(td).split("@")[1],td.size());
hostInfo = getNameSrc(td).split("@");
if(pn.getTd()>3) {
if(!suppMap.get(pn.getTd()-1).isEmpty()) {
pn.setParent(suppMap.get(pn.getTd()-1));
}
if(suppMap.get(pn.getTd())!=null){
suppMap.remove(pn.getTd());
}
suppMap.put(pn.getTd(), pn.getNodeName());
projectTree.addNodeToTree(pn);
} else {
projectTree.addNodeToTree(pn);
suppMap.put(pn.getTd(), pn.getNodeName());
//out.write(pn.toString()+"\n");
}
}
}
ArrayList<ProjectNode> pns = projectTree.getNodeList();
Collections.sort(pns, Comparator.comparing(ProjectNode::getTd));
Collections.reverse(pns);
projectTree.setNodeList(pns);
List<ProjectNode> finalList = new ArrayList<ProjectNode>();
for(ProjectNode pn :pns ) {
if(pn.getTd()==3) {
finalList.add(pn);
}else {
projectTree.addToParent(pn);
}
}
Collections.reverse(finalList);
for(ProjectNode pn : finalList) {
Collections.sort(pn.getChildren());
}
out.write(finalList.get(12).getChildren().get(4).getChildren().toString());
out.close();
System.out.println(finalList.size());
return finalList;
}
项目树类
public class ProjectTree {
private ProjectNode rootNode;
private ArrayList<ProjectNode> NodeList;
public ProjectTree() {
super();
this.NodeList = new ArrayList<ProjectNode>();
}
public ProjectTree(ProjectNode rootNode, ArrayList<ProjectNode> nodeList) {
super();
this.rootNode = rootNode;
NodeList = nodeList;
}
public ArrayList<ProjectNode> groupHosts(){
return this.NodeList;
}
public void addToParent(ProjectNode pn) {
for(ProjectNode pnA :this.NodeList) {
if(pnA.getNodeName().equals(pn.getParent())) {
if(pnA.getChildren()!=null && pnA.getChildren().size()!=0) {
pnA.sortChildren();
}
pnA.addChlild(pn);
}
}
}
public ProjectNode getRootNode() {
return rootNode;
}
public void setRootNode(ProjectNode rootNode) {
this.rootNode = rootNode;
}
public ArrayList<ProjectNode> getNodeList() {
return NodeList;
}
public void setNodeList(ArrayList<ProjectNode> nodeList) {
NodeList = nodeList;
}
}
ProjectNode.class
public class ProjectNode implements Comparable<ProjectNode>{
private String parent;
private String nodeName;
private String nodeHref;
private boolean hasChild;
private int td;
private ArrayList<ProjectNode> children;
public ProjectNode() {
super();
// TODO Auto-generated constructor stub
}
public ProjectNode( String nodeName, String nodeHref, int td) {
super();
this.nodeName = nodeName;
this.nodeHref = nodeHref;
this.hasChild =false;
this.td=td;
}
public void addChlild(ProjectNode pn) {
if(children!=null) {
this.children.add(pn);
}else {
this.children = new ArrayList<ProjectNode>();
this.children.add(pn);
}
}
public List<ProjectNode> getChildren() {
return children;
}
public void sortChildren() {
Collections.sort(this.getChildren());;
//Collections.sort(this.getChildren(), Comparator.comparing(ProjectNode::getNodeName));
//System.out.println(this.children.toString());
}
public void setChildren(ArrayList<ProjectNode> children) {
this.children = children;
}
public int getTd() {
return td;
}
public void setTd(int td) {
this.td = td;
}
public boolean isHasChild() {
return hasChild;
}
public void setHasChild(boolean hasChild) {
this.hasChild = hasChild;
}
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
public String getNodeHref() {
return nodeHref;
}
public void setNodeHref(String nodeHref) {
this.nodeHref = nodeHref;
}
@Override
public String toString() {
return "ProjectNode [parent=" + parent + ", nodeName=" + nodeName + ", nodeHref=" + nodeHref + ", hasChild="
+ hasChild + ", td=" + td + ", children=" +"]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((children == null) ? 0 : children.hashCode());
result = prime * result + (hasChild ? 1231 : 1237);
result = prime * result + ((nodeHref == null) ? 0 : nodeHref.hashCode());
result = prime * result + ((nodeName == null) ? 0 : nodeName.hashCode());
result = prime * result + ((parent == null) ? 0 : parent.hashCode());
result = prime * result + td;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ProjectNode other = (ProjectNode) obj;
if (children == null) {
if (other.children != null)
return false;
} else if (!children.equals(other.children))
return false;
if (hasChild != other.hasChild)
return false;
if (nodeHref == null) {
if (other.nodeHref != null)
return false;
} else if (!nodeHref.equals(other.nodeHref))
return false;
if (nodeName == null) {
if (other.nodeName != null)
return false;
} else if (!nodeName.equals(other.nodeName))
return false;
if (parent == null) {
if (other.parent != null)
return false;
} else if (!parent.equals(other.parent))
return false;
if (td != other.td)
return false;
return true;
}
@Override
public int compareTo(ProjectNode o) {
// TODO Auto-generated method stub
return nodeName.compareTo(o.getNodeName());
}
}
我会使用递归将所有节点分组在 corect 位置,但我有相同的错误(使用 stackoverflow),所以我不得不使用 addToParent() 函数。
【问题讨论】:
-
我认为私有数组可能不是问题所在。它可能是一个空数组,这意味着一个元素没有子元素。但是请您发布更多项目节点的代码吗?你指的是什么解析器?
-
错误可能在递归函数中,请贴出来
-
你确定你的“树”中没有循环吗?
-
你能试着把你的问题缩小到minimal reproducible example吗?这是很多代码,我怀疑重现您的问题需要所有这些。
-
@MaxVollmer 我试过了......它工作......所以我想我需要再看看它,并弄清楚我把它搞砸了
标签: java json infinite-loop