• 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     }
    27
    28 }

    通过递归以目录格式解析层级关系,把准备的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" : null
    11         }, {
    12             "children" : [],
    13             "id" : "hc112",
    14             "message" : {
    15                 "age" : 1,
    16                 "name" : "name"
    17             },
    18             "parent" : null
    19         } ],
    20         "id" : "hc11",
    21         "message" : {
    22             "age" : 1,
    23             "name" : "name"
    24         },
    25         "parent" : null
    26     }, {
    27         "children" : [],
    28         "id" : "hc12",
    29         "message" : {
    30             "age" : 1,
    31             "name" : "name"
    32         },
    33         "parent" : null
    34     } ],
    35     "id" : "hc1",
    36     "message" : {
    37         "age" : 1,
    38         "name" : "name"
    39     },
    40     "parent" : null
    41 }, {
    42     "children" : [ {
    43         "children" : [],
    44         "id" : "hc21",
    45         "message" : {
    46             "age" : 1,
    47             "name" : "name"
    48         },
    49         "parent" : null
    50     } ],
    51     "id" : "hc2",
    52     "message" : {
    53         "age" : 1,
    54         "name" : "name"
    55     },
    56     "parent" : null
    57 } ]

    把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 == 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 = 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 = (Gender) value;
     7                     return tmpValue.getValue();
     8                 }
     9                 return value.toString();
    10             }
    11 
    12             @Override
    13             public Object processArrayValue(Object arg0, JsonConfig arg1) {
    14                 // TODO Auto-generated method stub
    15                 return null;
    16             }
    17         });

    在处理json的时候可能有提供一些封装好的API,但是掌握基础是很重要的。。。。。。。

  • 相关阅读:
    VS2010插件及快捷键设置
    在Windows程序中启用console输出-2016.01.04
    使用VAssistX给文件和函数添加注释-2015.12.31
    windows在远程桌面连接中使用命令行参数
    windows网络编程-2015.12.29
    grep使用
    linux程序调试常用命令
    vim使用笔记
    infusion度量金字塔数据解释
    MVc Forms Membership rolemanage 角色权限验证管理
  • 原文地址:https://www.cnblogs.com/sun-space/p/5823999.html
Copyright © 2020-2023  润新知