使用json-lib完成json的序列化和反序列化
使用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 = 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)+"'}");
// 使用JSONObject将json序列化对象
JSONObject obj=JSONObject.fromObject(str.toString());
// 将JOSNObject对象转换成pojo对象
Emp emp=(Emp) JSONObject.toBean(obj,Emp.class);
System.out.println(emp.getBirthday());
}
这里需要注意的是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.fromObject(str.toString());
//使用JSONArray转换成集合
List
for (Emp emp : list) {
System.out.println(emp.getEmpname());
System.out.println(emp.getBirthday());
System.out.println(emp.getDept().getDepname());
}
}
这里需要注意的是json的数组用法为[]
3.对象反序列化成json
/**
*通过对象转换成json
*@author凤生禾予
*/
public void objectToJson(){
ClassPathXmlApplicationContext xa=new
ClassPathXmlApplicationContext("applicationContext.xml");
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)使用jsonConfig的setExcludes的方法进行过滤,将所需要过滤的字段名传入setExcludes方法
public void objectToJson(){
ClassPathXmlApplicationContext xa=new
ClassPathXmlApplicationContext("applicationContext.xml");
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)使用jsonConfig的setJsonPropertyFilter进行属性过滤,过滤器中返回true表示过滤该字段,返回false表示可以转换该字段
public void objectToJson(){
ClassPathXmlApplicationContext xa=new
ClassPathXmlApplicationContext("applicationContext.xml");
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)使用jsonConfig的setCycleDetectionStrategy()方法进行忽略死循环使用jsonConfig的registerJsonValueProcessor()进行属性转换设置
/**
*通过对象转换成json
*@author凤生禾予
*/
public void objectToJson(){
ClassPathXmlApplicationContext xa=new
ClassPathXmlApplicationContext("applicationContext.xml");
EmpDAO dao=(EmpDAO) xa.getBean("EmpDAO");
//查找对象
Emp emp=dao.findById(27);
//创建jsonConfig对象
JsonConfig config=new JsonConfig();
//设置循环策略为忽略解决json最头疼的问题死循环
config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
//设置 json转换的处理器用来处理日期类型
//凡是反序列化Date类型的对象,都会经过该处理器进行处理
config.registerJsonValueProcessor(Date.class, new JsonValueProcessor() {
//参数1 :属性名参数2:json对象的值参数3:jsonConfig对象
public Object processObjectValue(String arg0, Object arg1, JsonConfig arg2) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd
HH:mm:ss");
Date d=(Date) arg1;
return sdf.format(d);
}
public Object processArrayValue(Object arg0, JsonConfig arg1) { return null;
}
});
String s=JSONObject.fromObject(emp,config).toString();
System.out.println(s);
}
这种方案可以解决死循环问题和日期格式化的问题。
结果:
{"birthday":"2010-08-01 00:00:00","dept":{"depid":1,"depname":"开发部","emps":[{"birthday":"2009-08-01
00:00:00","dept":null,"empid":30,"empname":"田七
"},null]},"empid":27,"empname":"王五"}
3.集合反序列化成json
/**
*通过集合转换成json
*@author凤生禾予
*/
public void arrayToJson(){
ClassPathXmlApplicationContext xa=new
ClassPathXmlApplicationContext("applicationContext.xml");
EmpDAO dao=(EmpDAO) xa.getBean("EmpDAO");
List
JsonConfig config=new JsonConfig();
config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
config.registerJsonValueProcessor(Date.class, new JsonValueProcessor() {
@Override
public Object processObjectValue(String arg0, Object arg1, JsonConfig arg2) {
// TODO Auto-generated method stub
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd
HH:mm:ss");
Date d=(Date) arg1;
return sdf.format(d);
}
@Override
public Object processArrayValue(Object arg0, JsonConfig arg1) { // TODO Auto-generated method stub
return null;
}
});
String s=JSONArray.fromObject(emps,config).toString();
System.out.println(s);
}
这个和上面没有太多区别。
总结:使用json-lib进行对象的序列化和反序列化的文档比较少,在工作中进行及时总结经验是一个比较好的方式。
json-lib对象的序列化比较简单,重要的是使用JSONObject和JSONArray两个对象,这两个对象进行序列化pojo对象之前,必须将json转换成对应的JSONObject和JSONArray对象。
json-lib对象的反序列化相对复杂些,因为反序列时json-lib通过代理对对象进行反射操作将对象生成json,特别在Hibernate中容易产生死循环操作,而且对一些日期和其他的复杂对象的转换可能和我们的预期不一致,所以一定要对jsonConfig对象进行详细研究,其中的setExcludes,setJsonPropertyFilter,setCycleDetectionStrategy,registerJso nValueProcessor等方法相当有用。
希望我今天的这些心得对大家有一些帮助。
Json数据格式的使用方法入门教程
JSON 数据格式解析 和 XML 一样,JSON 也是基于纯文本的数据格式。由于 JSON 天生是为JavaScript 准备的,因此,JSON 的数据格式非常简单,您可以用 JSON 传输一个简单的 String,Number,Boolean,也可以传输一个数组,或者一个复杂的Object 对象。 String,Number 和 Boolean 用 JSON 表示非常简单。例如,用 JSON 表示一个简单的 String “ abc ”,其格式为: "abc" 除了字符 ",\,/ 和一些控制符(\b,\f,\n,\r,\t)需要编码外,其他 Unicode 字符可以直接输出。下图是一个 String 的完整表示结构: 图 1. String 的完整表示结构 一个 Number 可以根据整型或浮点数表示如下:
图 2. Number 的表示结构 这与绝大多数编程语言的表示方法一致,例如: 12345(整数) -3.9e10(浮点数) Boolean 类型表示为 true 或 false 。此外,JavaScript 中的 null 被表示为 null,注意,true、false 和 null 都没有双引号,否则将被视为一个String 。 JSON 还可以表示一个数组对象,使用 [] 包含所有元素,每个元素用逗号分隔,元素可以是任意的 Value,例如,以下数组包含了一个 String,Number,Boolean 和一个 null: Object 对象在 JSON 中是用 {} 包含一系列无序的 Key-Value 键值对表示的,实际上此处的 Object 相当于 Java 中的 Map
使用JSON的方法
Java代码转换成json代码 1.import net.sf.json.JSONArray; 2.import net.sf.json.JSONObject; 1. List集合转换成json代码 List list = new ArrayList(); list.add( "first" ); list.add( "second" ); JSONArray jsonArray2 = JSONArray.fromObject( list ); 2. Map集合转换成json代码 Map map = new HashMap(); map.put("name", "json"); map.put("bool", Boolean.TRUE); map.put("int", new Integer(1)); map.put("arr", new String[] { "a", "b" }); map.put("func", "function(i){ return this.arr[i]; }"); JSONObject json = JSONObject.fromObject(map); 3. Bean转换成json代码 JSONObject jsonObject = JSONObject.fromObject(new JsonBean()); 4. 数组转换成json代码 boolean[] boolArray = new boolean[] { true, false, true }; JSONArray jsonArray1 = JSONArray.fromObject(boolArray);
Json概念及jsoncpp编程接口说明
JSON简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。 JSON建构于两种结构: ?对象,即“名称/值”对的集合(A collection of name/value pairs)。一个对象可以包含多个“名称/值”对,可以理解为对象的属性。 ?数组,值的有序列表(An ordered list of values)。 其中,“名称”是一个字符串,而“值”可以是多种数据类型,包括:字符串、数字、布尔值、null值、对象、数组。由此可见,JSON中数组和对象之间是可以相互嵌套的。 一个JSON文档被解释为一个“值”,这个值的类型可以是上面列出的任何类型。 这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。 JSON具有以下这些形式: 对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。 数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
json用法
JSON 语法是JavaScript 语法的子集。 JSON 语法规则 JSON 语法是JavaScript 对象表示法语法的子集。 ?数据在名称/值对中 ?数据由逗号分隔 ?花括号保存对象 ?方括号保存数组 JSON 名称/值对 JSON 数据的书写格式是:名称/值对。 名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值: 这很容易理解,等价于这条JavaScript 语句: JSON 值 JSON 值可以是: ?数字(整数或浮点数) ?字符串(在双引号中) ?逻辑值(true 或false) ?数组(在方括号中) ?对象(在花括号中) ?null JSON 对象 JSON 对象在花括号中书写: 对象可以包含多个名称/值对: 这一点也容易理解,与这条JavaScript 语句等价:
JSON 数组 JSON 数组在方括号中书写: 数组可包含多个对象: 在上面的例子中,对象"employees" 是包含三个对象的数组。每个对象代表一条关于某人(有姓和名)的记录。 JSON 使用JavaScript 语法 因为JSON 使用JavaScript 语法,所以无需额外的软件就能处理JavaScript 中的JSON。 通过JavaScript,您可以创建一个对象数组,并像这样进行赋值: 例子 可以像这样访问JavaScript 对象数组中的第一项: 返回的内容是:
可以像这样修改数据: JSON 实例- 来自字符串的对象 创建包含JSON 语法的JavaScript 字符串: 由于JSON 语法是JavaScript 语法的子集,JavaScript 函数eval() 可用于将JSON 文本转换为JavaScript 对象。 eval() 函数使用的是JavaScript 编译器,可解析JSON 文本,然后生成JavaScript 对象。必须把文本包围在括号中,这样才能避免语法错误: 在网页中使用JavaScript 对象: 例子