如何用java递归生成带children的json串

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用java递归生成带children的json串相关的知识,希望对你有一定的参考价值。

这个问题有点没意义,因为java已经有相应的jar了,不论是阿里的fastjson,还是gson,又或者是jackson,都是已经很成熟的jar了。如果非要自己去写的话,就需要用到反射了。简单来说,就是获取对象的所有属性。复杂说的话,要判断对象的属性,判断属性类型,判断属性值是否为null,判断对象是否是有transient修饰,判断字符串里面是否有双引号等等。然后通过StringBuffer或是StringBuilder去拼接字符串,来生成json串,至于是StringBuffer还是StringBuilder就看你的需要再决定了 参考技术A 先递归出一个 node对象,再将node对象转换成json串。直接进行字符串的json操作不建议。

class Node
private String id;
private String parentId;
private List<Node> children;
public void addChildren(Node child)
getChildren().add(child);

public List<Node> getChildren();

public String transformTojson(Node node ,StringBuffer jsonStr)
//递归
if(jsonStr ==null)
StringBuffer jsonStr=new ();

if(node.id!=null)
//拼接父节点json串
jsonStr.append(id:node.id,children:#&children);

List childNodeList = node.getChildren();

StringBuffer childrenSB = new();
for( Node node :childNodeList)
childrenSB=transformTojson(node);

sonStr.replaceFirst("#&children",childrenSB);
return jsonStr;



伪代码大概这样。
transformTojson方法可以不自己写,直接使用第三方工具jar包的json转化方法,比如gjson。
参考技术B import java.io.IOException;
import java.util.Collection;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;

/**
* 简单封装Jackson,实现JSON String<->Java Object的Mapper.
*
* 封装不同的输出风格, 使用不同的builder函数创建实例.
*
*/
public class JsonMapper

private static Logger logger = LoggerFactory.getLogger(JsonMapper.class);

private ObjectMapper mapper;

public JsonMapper()
this(null);


public JsonMapper(Include include)
mapper = new ObjectMapper();
// 设置输出时包含属性的风格
if (include != null)
mapper.setSerializationInclusion(include);

// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);


public static JsonMapper alwaysMapper()
return new JsonMapper(Include.ALWAYS);


public static JsonMapper nonNullMapper()
return new JsonMapper(Include.NON_NULL);


/**
* 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用.
*/
public static JsonMapper nonEmptyMapper()
return new JsonMapper(Include.NON_EMPTY);


/**
* 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式,建议在内部接口中使用。
*/
public static JsonMapper nonDefaultMapper()
return new JsonMapper(Include.NON_DEFAULT);


/**
* Object可以是POJO,也可以是Collection或数组。 如果对象为Null, 返回"null". 如果集合为空集合, 返回"[]".
*/
public String toJson(Object object)

try
return mapper.writeValueAsString(object);

catch (IOException e)
logger.warn("write to json string error:" + object, e);
return null;



/**
* 反序列化POJO或简单Collection如List<String>.
*
* 如果JSON字符串为Null或"null"字符串, 返回Null. 如果JSON字符串为"[]", 返回空集合.
*
* 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String, JavaType)
*
* @see #fromJson(String, JavaType)
*/
public <T> T fromJson(String jsonString, Class<T> clazz)
if (StringUtils.isEmpty(jsonString))
return null;


try
return mapper.readValue(jsonString, clazz);

catch (IOException e)
logger.warn("parse json string error:" + jsonString, e);
return null;



/**
* 反序列化复杂Collection如List<Bean>,
* 先使用createCollectionType()或contructMapType()构造类型, 然后调用本函数.
*
* @see #createCollectionType(Class, Class...)
*/
public <T> T fromJson(String jsonString, JavaType javaType)
if (StringUtils.isEmpty(jsonString))
return null;


try
return (T) mapper.readValue(jsonString, javaType);

catch (IOException e)
logger.warn("parse json string error:" + jsonString, e);
return null;



/**
* 构造Collection类型.
*/
public JavaType contructCollectionType(Class<? extends Collection> collectionClass, Class<?> elementClass)
return mapper.getTypeFactory().constructCollectionType(collectionClass, elementClass);


/**
* 构造Map类型.
*/
public JavaType contructMapType(Class<? extends Map> mapClass, Class<?> keyClass, Class<?> valueClass)
return mapper.getTypeFactory().constructMapType(mapClass, keyClass, valueClass);


/**
* 当JSON里只含有Bean的部分属性时,更新一个已存在Bean,只覆盖该部分的属性.
*/
public void update(String jsonString, Object object)
try
mapper.readerForUpdating(object).readValue(jsonString);

catch (JsonProcessingException e)
logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);

catch (IOException e)
logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);



/**
* 输出JSONP格式数据.
*/
public String toJsonP(String functionName, Object object)
return toJson(new JSONPObject(functionName, object));


/**
* 设定是否使用Enum的toString函数来读写Enum, 为False时时使用Enum的name()函数来读写Enum, 默认为False.
* 注意本函数一定要在Mapper创建後, 所有的读写动作之前调用.
*/
public void enableEnumUseToString()
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);


/**
* 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。
* 默认会先查找jaxb的annotation,如果找不到再找jackson的。
*/
public void enableJaxbAnnotation()
JaxbAnnotationModule module = new JaxbAnnotationModule();
mapper.registerModule(module);


/**
* 取出Mapper做进一步的设置或使用其他序列化API.
*/
public ObjectMapper getMapper()
return mapper;

参考技术C 代码很简单就两个类一个TreeNode.java 和一个测试类Test.java(可直接运行)
在运行之前需要以下公共类:
commons-beanutils.jar
commons-collections.jar
commons-lang.jar
commons-logging.jar
ezmorph-1.0.6.jar
json-lib-2.3-jdk15.jar
package com.test;
import java.util.ArrayList;
public class TreeNode
private String id;
private String pid;
private String name;
private String remark;
private ArrayList<TreeNode> children = new ArrayList<TreeNode>();
public TreeNode(String id, String pid, String name, String remark)
this.id = id;
this.pid = pid;
this.name = name;
this.remark = remark;

public void add(TreeNode node) //递归添加节点
if ("0".equals(node.pid))
this.children.add(node);
else if (node.pid.equals(this.id))
this.children.add(node);
else
for (TreeNode tmp_node : children)
tmp_node.add(node);



public String getId()
return id;

public void setId(String id)
this.id = id;

public String getName()
return name;

public void setName(String name)
this.name = name;


public String getRemark()
return remark;

public void setRemark(String remark)
this.remark = remark;

public ArrayList<TreeNode> getChildren()
return children;

public void setChildren(ArrayList<TreeNode> children)
this.children = children;



测试类Test.java
package com.test;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class Test
public static void main(String[] args)
TreeNode root = new TreeNode("0", "0", "000000", "00JJJ");
TreeNode node = null;
node = new TreeNode("1", "0", "111111", "11AAA");
root.add(node);
node = new TreeNode("2", "0", "222222", "11BBB");
root.add(node);
node = new TreeNode("3", "2", "333333", "11CCC");
root.add(node);
// JSONObject obj = JSONObject.fromObject(root);//有根
JSONArray obj = JSONArray.fromObject(root.getChildren());// 不要根
System.out.println(obj.toString());

参考技术D 你自己 看看 就可以写了

package com.bochy.common.utils;

/*
*
* 转换JSON帮助�??
*
* */
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JsonUtils
public static String stringToJson(String s)
if (s == null)
return nullToJson();

StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++)
char ch = s.charAt(i);
switch (ch)
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
case '/':
sb.append("\\/");
break;
default:
if (ch >= '\u0000' && ch <= '\u001F')
String ss = Integer.toHexString(ch);
sb.append("\\u");
for (int k = 0; k < 4 - ss.length(); k++)
sb.append('0');

sb.append(ss.toUpperCase());
else
sb.append(ch);



return sb.toString();

public static String nullToJson()
return "";

public static String objectToJson(Object obj)
StringBuilder json = new StringBuilder();
if (obj == null)
json.append("\"\"");
else if (obj instanceof Number)
json.append(numberToJson((Number) obj));
else if (obj instanceof Boolean)
json.append(booleanToJson((Boolean) obj));
else if (obj instanceof String)
json.append("\"").append(stringToJson(obj.toString())).append("\"");
else if (obj instanceof Object[])
json.append(arrayToJson((Object[]) obj));
else if (obj instanceof List)
json.append(listToJson((List<?>) obj));
else if (obj instanceof Map)
json.append(mapToJson((Map<?, ?>) obj));
else if (obj instanceof Set)
json.append(setToJson((Set<?>) obj));
else
json.append(beanToJson(obj));

return json.toString();

public static String numberToJson(Number number)
return number.toString();

public static String booleanToJson(Boolean bool)
return bool.toString();

/** *//**
* @param bean
* bean对象
* @return String
*/
public static String beanToJson(Object bean)
StringBuilder json = new StringBuilder();
json.append("");
PropertyDescriptor[] props = null;
try
props = Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors();
catch (IntrospectionException e)

if (props != null)
for (int i = 0; i < props.length; i++)
try
String name = objectToJson(props[i].getName());
String value = objectToJson(props[i].getReadMethod()
.invoke(bean));
json.append(name);
json.append(":");
json.append(value);
json.append(",");
catch (Exception e)


json.setCharAt(json.length() - 1, '');
else
json.append("");

return json.toString();

/** *//**
* @param list
* list对象
* @return String
*/
public static String listToJson(List<?> list)
StringBuilder json = new StringBuilder();
json.append("[");
if (list != null && list.size() > 0)
for (Object obj : list)
json.append(objectToJson(obj));
json.append(",");

json.setCharAt(json.length() - 1, ']');
else
json.append("]");

return json.toString();

/** *//**
* @param array
* 对象数组
* @return String
*/
public static String arrayToJson(Object[] array)
StringBuilder json = new StringBuilder();
json.append("[");
if (array != null && array.length > 0)
for (Object obj : array)
json.append(objectToJson(obj));
json.append(",");

json.setCharAt(json.length() - 1, ']');
else
json.append("]");

return json.toString();

/** *//**
* @param map
* map对象
* @return String
*/
public static String mapToJson(Map<?, ?> map)
StringBuilder json = new StringBuilder();
json.append("");
if (map != null && map.size() > 0)
for (Object key : map.keySet())
json.append(objectToJson(key));
json.append(":");
json.append(objectToJson(map.get(key)));
json.append(",");

json.setCharAt(json.length() - 1, '');
else
json.append("");

return json.toString();

/** *//**
* @param set
* 集合对象
* @return String
*/
public static String setToJson(Set<?> set)
StringBuilder json = new StringBuilder();
json.append("[");
if (set != null && set.size() > 0)
for (Object obj : set)
json.append(objectToJson(obj));
json.append(",");

json.setCharAt(json.length() - 1, ']');
else
json.append("]");

return json.toString();

如何用Python解析多层嵌套的JSON?

近期遇到用Python解析多层嵌套的JSON的困难,通过json.loads转为dict类型后,使用dict['key']来调取value,会提示TypeError: string indices must be integersJSON文件如链接:https://api.doctorxiong.club/v1/fund?code=010300,009683,006355,006697JSON的第二层是个二维表,目标就是第二层,读取出来写到xls表中

参考技术A 可以根据jpath解析keyword或路径。
也可以根据实际结果进行剥洋葱似的层层解析处理。
参考技术B 单纯从你给的这个链接,使用requests.get(url).json()
这样拿到的数据,是dict类型,取值正常.....
参考技术C

本回答被提问者采纳

以上是关于如何用java递归生成带children的json串的主要内容,如果未能解决你的问题,请参考以下文章

如何用java递归生成带children的json串啊?数据集已经有了在下面。

如何用Java拼接JSON方式遍历整个树形节点

如何用java程序读取带密码(密码已知)的office文档。

java构建树形列表(带children属性)

如何用java生成有规律的字符串?

如何用Python解析多层嵌套的JSON?