使用json-lib完成json的序列化和反序列化2011-07-29 14:07:43
分类: 默认分类标签:软件  java  json.
json的序列化和反序列化在现在的javaweb中特别是ajax中使用的比较频繁,现在本人就这种技术提出自己的使用心得。
我的pojo对象的结构是这样的
部门表和员工表    1对多的关系
部门对象
public class Dept implements java.io.Serializable {
    private Integer depid;//部门ID
    private String depname;//部门名称
    private Set emps = json转换对象new HashSet(0);//员工集合
}
员工对象
public class Emp implements java.io.Serializable {
    private Integer empid;//员工id
    private Dept dept;//部门
    private String empname;//员工名称
    private Date birthday;//生日
}
1.json字符串序列化成对象
/**
* 通过json转换成对象
* @author 凤生禾予
*/
public void jsonToObject(){
    Date d=new Date();
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    StringBuffer str=new StringBuffer();
    // json字符串
    str.append("{empid:1,dept:{depid:1,depname:'开发部'},empname:'张三',birthday:'"+sdf.format(d)+"'}");
    // 使用JSONObjectjson序列化对象
    JSONObject obj=JSONObject.String());
    // JOSNObject对象转换成pojo对象
    Emp emp=(Emp) Bean(obj,Emp.class);
    System.out.Birthday());
}
这里需要注意的是json字符串的写法以{}表示一个对象,字符串必须加引号
2json字符串序列化成集合
/**
* 通过json转换成集合
* @author 凤生禾予
*/
public void jsonToArray(){
    Date d=new Date();
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    StringBuffer str=new StringBuffer();
    //json字符串
    str.append("[");
    str.append("{empid:1,dept:{depid:1,depname:'开发部'},empname:'张三',birthday:'"+sdf.format(d)+"'}");
    str.append(",");
    str.append("{empid:2,dept:{depid:1,depname:'开发部'},empname:'李四',birthday:'"+sdf.format(d)+"'}");
    str.append("]");
    //json转换成JSONArray对象
    JSONArray arr=JSONArray.String());
    //使用JSONArray转换成集合
    List<Emp> List(arr,Emp.class);
    for (Emp emp : list) {
        System.out.Empname());
        System.out.Birthday());
        System.out.Dept().getDepname());
    }
}
这里需要注意的是json的数组用法为[]
3.对象反序列化成json
/**
  * 通过对象转换成json
  * @author 凤生禾予
  */
public void objectToJson(){
    ClassPathXmlApplicationContext xa=new ClassPathXmlApplicationContext("l");
    EmpDAO dao=(EmpDAO) xa.getBean("EmpDAO");
    //查对象
    Emp emp=dao.findById(27);
    String s=JSONObject.fromObject(emp).toString();
    System.out.println(s);
}
这里会有2个问题
1.pojo中对象存在有死循环问题,部门类中有员工对象的集合,员工类中有部门的对象,json-lib反序列化中会进行双向转换,从而形成死循环,会报一个json-lib的经典异常:
Exception in thread "main" net.sf.json.JSONException: There is a cycle in the hierarchy!
2.日期类型转换
json-lib转换出来的日期类型格式
"birthday":{"date":1,"day":0,"hours":0,"minutes":0,"month":7,"nanos":0,"seconds":0,"time":1280592000000,"timezoneOffset":-480,"year":110}
那么我们如果想要yyyy-MM-dd HH:mm:ss 这种格式的怎么办呢?
那么解决方案有3
都必须使用jsonConfig对象进行处理
(1)使用jsonConfigsetExcludes的方法进行过滤,将所需要过滤的字段名传入setExcludes方法
    public void objectToJson(){
        ClassPathXmlApplicationContext xa=new ClassPathXmlApplicationContext("l");
        EmpDAO dao=(EmpDAO) xa.getBean("EmpDAO");
        //查对象
        Emp emp=dao.findById(27);
        //创建jsonConfig对象
        JsonConfig config=new JsonConfig();
        //设置过滤字段
        config.setExcludes(new String[]{"dept"});
        String s=JSONObject.fromObject(emp,config).toString();
        System.out.println(s);
    }
2)使用jsonConfigsetJsonPropertyFilter进行属性过滤,过滤器中返回true表示过滤该字段,返回false表示可以转换该字段
    public void objectToJson(){
        ClassPathXmlApplicationContext xa=new ClassPathXmlApplicationContext("applica
l");
        EmpDAO dao=(EmpDAO) xa.getBean("EmpDAO");
        //查对象
        Emp emp=dao.findById(27);
        //创建jsonConfig对象
        JsonConfig config=new JsonConfig();
        //设置过滤字段
        config.setJsonPropertyFilter(new PropertyFilter() {
            public boolean apply(Object arg0, String arg1, Object arg2) {
                if("dept".equals(arg1)){
                    return true;
                }
                return false;
            }
        });
        String s=JSONObject.fromObject(emp,config).toString();
        System.out.println(s);
    }
上述两种解决方案可以解决部分问题,但是json-lib使用代理进行反射,所以如果想要部门表的信息,而去过滤部门表的员工对象,这样还是解决不了。这样可以使用更简单有效的方案
3)使用jsonConfigsetCycleDetectionStrategy()方法进行忽略死循环
    使用jsonConfigregisterJsonValueProcessor()进行属性转换设置
  /**
    * 通过对象转换成json
    * @author 凤生禾予
    */
    public void objectToJson(){
        ClassPathXmlApplicationContext xa=new ClassPathXmlApplicationContext("l");
        EmpDAO dao=(EmpDAO) xa.getBean("EmpDAO");
        //查对象
        Emp emp=dao.findById(27);
        //创建jsonConfig对象
        JsonConfig config=new JsonConfig();
        //设置循环策略为忽略    解决json最头疼的问题 死循环
        config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
        //设置 json转换的处理器  用来处理日期类型
        //凡是反序列化Date类型的对象,都会经过该处理器进行处理

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。