首页 > 代码库 > 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与对象的转化 递归