首页 > 代码库 > java处理json与对象的转化 递归
java处理json与对象的转化 递归
整个类是一个case,总结了我在使用java处理json的时候遇到的问题,还有级联关系的对象如何遍历,json和对象之间的转换!
对于对象json转换中遇到的问题我参考了一篇博客,http://blog.csdn.net/xq328220454/article/details/39256589
很有益处,我在文章的后半部分照搬了过来!
首先准备数据,准备了一堆具有主子关系的对象,包含普通属性id,父对象parent,子集合list<HeadCell>,还有关联对象message;
1 @Before 2 public void setUp() throws Exception { 3 Message message = new Message("name", 1); 4 HeadCell hc1 = new HeadCell(); 5 HeadCell hc2 = new HeadCell(); 6 HeadCell hc11 = new HeadCell(); 7 HeadCell hc12 = new HeadCell(); 8 HeadCell hc21 = new HeadCell(); 9 HeadCell hc111 = new HeadCell();10 HeadCell hc112 = new HeadCell();11 12 hc111.setId("hc111");13 hc111.setMessage(message);14 15 hc112.setId("hc112");16 hc112.setMessage(message);17 18 hc11.setId("hc11");19 hc11.setMessage(message);20 21 hc12.setId("hc12");22 hc12.setMessage(message);23 24 hc21.setId("hc21");25 hc21.setMessage(message);26 27 hc1.setId("hc1");28 hc1.setMessage(message);29 30 hc2.setId("hc2");31 hc2.setMessage(message);32 33 List<HeadCell> hcs11 = new ArrayList<>();34 hcs11.add(hc111);35 hcs11.add(hc112);36 hc11.setChildren(hcs11);37 hc111.setParent(hc11);38 hc112.setParent(hc11);39 40 List<HeadCell> hcs1 = new ArrayList<>();41 hcs1.add(hc11);42 hcs1.add(hc12);43 hc1.setChildren(hcs1);44 hc11.setParent(hc1);45 hc12.setParent(hc1);46 47 List<HeadCell> hcs2 = new ArrayList<>();48 hcs2.add(hc21);49 hc2.setChildren(hcs2);50 51 headCells.add(hc1);52 headCells.add(hc2);53 }
1 public class Message { 2 private String name; 3 private Integer age; 4 5 public Message() {} 6 7 public Message(String name, Integer age) { 8 this.name = name; 9 this.age = age;10 }11 12 public String getName() {13 return name;14 }15 16 public void setName(String name) {17 this.name = name;18 }19 20 public Integer getAge() {21 return age;22 }23 24 public void setAge(Integer age) {25 this.age = age;26 }2728 }
通过递归以目录格式解析层级关系,把准备的list以树形的方式打印处理
1 @Test 2 public void chart() { 3 String str = ""; 4 buildChart(headCells, str); 5 } 6 7 private void buildChart(List<HeadCell> headCells, String str) { 8 str += "++"; 9 for (int i = 0; i < headCells.size(); i++) {10 HeadCell headCell = headCells.get(i);11 if (headCell.getChildren() != null && headCell.getChildren().size() > 0) {12 System.out.println(str + headCell.getId());13 buildChart(headCell.getChildren(), str);14 } else {15 System.out.println(str + headCell.getId());16 }17 }18 }
打印结果为:
++hc1++++hc11++++++hc111++++++hc112++++hc12++hc2++++hc21
处理List<HeadCell>转化为jsonarray,当然对象是转换为jsonObject,还有一种是继承了ArrayList的对象,我有遇到过这种情况,忘了是怎么处理的了
这里转换的时候使用了config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);是因为parent自关联会无限递归下去,所以这解析出json的值
parent为空
1 @Test 2 public void proHeadCell2Json() { 3 JsonConfig config = new JsonConfig(); 4 // config.setExcludes(new String[]{}); 5 config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT); 6 try { 7 String array = JSONArray.fromObject(headCells, config).toString(); 8 System.out.println(array); 9 } catch (Exception e) {10 e.printStackTrace();11 }12 }
list对象转成json结果为
1 [ { 2 "children" : [ { 3 "children" : [ { 4 "children" : [], 5 "id" : "hc111", 6 "message" : { 7 "age" : 1, 8 "name" : "name" 9 },10 "parent" : null11 }, {12 "children" : [],13 "id" : "hc112",14 "message" : {15 "age" : 1,16 "name" : "name"17 },18 "parent" : null19 } ],20 "id" : "hc11",21 "message" : {22 "age" : 1,23 "name" : "name"24 },25 "parent" : null26 }, {27 "children" : [],28 "id" : "hc12",29 "message" : {30 "age" : 1,31 "name" : "name"32 },33 "parent" : null34 } ],35 "id" : "hc1",36 "message" : {37 "age" : 1,38 "name" : "name"39 },40 "parent" : null41 }, {42 "children" : [ {43 "children" : [],44 "id" : "hc21",45 "message" : {46 "age" : 1,47 "name" : "name"48 },49 "parent" : null50 } ],51 "id" : "hc2",52 "message" : {53 "age" : 1,54 "name" : "name"55 },56 "parent" : null57 } ]
把json转为list对象,这里主要是级联列并不能转为级联关系的对象,会直接报错,所以我们需要递归json把每一级都转为一个对象,并且在转换时把children添加
为例外,这里要知道我们的parent是空的,message并不存在级联列,所以可以直接存在对象里面。那么我们需要建立他们的父关系和子关系,还是要递归处理!
1 @Test 2 public void proJson2HeadCell() { 3 JSONArray array = perpareHeadCell2Json(); 4 List<HeadCell> headCells = new ArrayList<>(); 5 for (int i = 0; i < array.size(); i++) { 6 JSONObject object = array.getJSONObject(i); 7 headCells.add(buildTierObj(object)); 8 } 9 }10 11 private HeadCell buildTierObj(JSONObject object) {12 HeadCell hc = new HeadCell();13 if (!StringUtils.equals("[]", object.getString("children"))) {14 hc = (HeadCell) JSONObject.toBean(object, HeadCell.class);15 hc.setChildren(new ArrayList<HeadCell>());16 hc.setParent(null);17 JSONArray array = object.getJSONArray("children");18 for (int i = 0; i < array.size(); i++) {19 HeadCell subHeadCell = buildTierObj(array.getJSONObject(i));20 subHeadCell.setParent(hc);21 hc.getChildren().add(subHeadCell);22 }23 } else {24 hc = (HeadCell) JSONObject.toBean(object, HeadCell.class);25 hc.setParent(null);26 }27 return hc;28 }29 30 public JSONArray perpareHeadCell2Json() {31 JsonConfig config = new JsonConfig();32 config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);33 try {34 JSONArray array = JSONArray.fromObject(headCells, config);35 return array;36 } catch (Exception e) {37 e.printStackTrace();38 }39 return null;40 }
下面是json转为对象中遇到的问题的总结:
在JSON-LIB中,要转换的对象包含自身对象时,会抛出异常There is a cycle in the hierarchy,解决办法,如下,这样不会保存自关联属性
1 JsonConfig config = new JsonConfig();2 config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
自定义要被转换的字段
1 JsonConfig config = new JsonConfig(); 2 config.setJsonPropertyFilter(new PropertyFilter() { 3 @Override 4 public boolean apply(Object arg0, String arg1, Object arg2) { 5 if (arg1.equals("id") || arg1.equals("serialNumber") || arg1.equals("productName")) { 6 return false; 7 } else { 8 return true; 9 }10 }11 });
解决延迟加载产生异常的问题(net.sf.json.JSONException:java.lang.reflect.InvocationTargetException)
1 JsonConfig config = new JsonConfig();2 // 解决延迟加载产生异常的问题3 config.setExcludes(new String[] { "handler", "hibernateLazyInitializer" });
解决数据库查询结果中,Date转换的问题(net.sf.json.JSONException:java.lang.reflect.InvocationTargetException)
1 JsonConfig config = new JsonConfig(); 2 config.registerJsonValueProcessor(java.util.Date.class, new JsonValueProcessor() { 3 @Override 4 public Object processArrayValue(Object obj, JsonConfig jsonconfig) { 5 return null; 6 } 7 8 @Override 9 public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {10 if (value =http://www.mamicode.com/= null)11 return "";12 // 注意:在判断几个父子级类型时要先判断子类型再判断父类型13 if (value instanceof java.sql.Date) {14 String str = DateFormat.getDateInstance(DateFormat.DEFAULT).format(value);15 return str;16 } else if (value instanceof java.sql.Timestamp || value instanceof java.util.Date) {17 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");18 String str = format.format(value);19 return str;20 }21 return value.toString();22 }23 });
有些字段的类型是枚举类型,可以在转换的时候将值设置为枚举类的value或者是label;
首先创建一个枚举类,这里我觉得我该写一篇关于枚举的博客,虽说不咋用。。。。。。
1 public enum Gender { 2 // 通过括号赋值,而且必须带有一个参构造器和一个属性跟方法,否则编译出错 3 // 赋值必须都赋值或都不赋值,不能一部分赋值一部分不赋值;如果不赋值则不能写构造器,赋值编译也出错 4 MAN("MAN"), WOMEN("WOMEN"); 5 6 private final String value; 7 8 // 构造器默认也只能是private, 从而保证构造函数只能在内部使用 9 Gender(String value) {10 this.value =http://www.mamicode.com/ value;11 }12 13 public String getValue() {14 return value;15 }16 }
配置config
1 JsonConfig config = new JsonConfig(); 2 config.registerJsonValueProcessor(Gender.class, new JsonValueProcessor() { 3 @Override 4 public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) { 5 if (value instanceof Gender) { 6 Gender tmpValue =http://www.mamicode.com/ (Gender) value; 7 return tmpValue.getValue(); 8 } 9 return value.toString();10 }11 12 @Override13 public Object processArrayValue(Object arg0, JsonConfig arg1) {14 // TODO Auto-generated method stub15 return null;16 }17 });
在处理json的时候可能有提供一些封装好的API,但是掌握基础是很重要的。。。。。。。
java处理json与对象的转化 递归