【Java】使用Json-lib序列化关联对象的异常解决



开发中遇到前端ajax向后台请求数据,后台使用JsonLib序列化对象后以json形式返回,但当遇到相互关联的对象时会出现问题:

Customer customer1 = new Customer(1001, "张三");
Customer customer2 = new Customer(1002, "李四");
Order order1 = new Order("order001", "广州", customer1);
Order order2 = new Order("order002", "上海", customer2);
Order order3 = new Order("order003", "山东", customer1);
customer1.getOrders().add(order1);
customer1.getOrders().add(order3);
customer2.getOrders().add(order2);
List<Customer> customers = new ArrayList<Customer>();
customers.add(customer1);
customers.add(customer2);
// 使用JSONArray序列化List
JSONArray jsonArray = JSONArray.fromObject(customers);
ServletActionContext.getResponse().getWriter().print(jsonArray.toString());

使用Jquery向后台请求数据:


$(function(){
	$.get("${pageContext.request.contextPath}/showCustomers.action", function(data){
		console.info(data);  // action返回json数据
	});
});

按以上代码时,customer关联了order,order也关联了customer,当两个对象相互关联时在序列化时就会出现以下异常:
net.sf.json.JSONException: There is a cycle in the hierarchy!
遇到这种情况,如果在序列化时只想序列化customer不序列化它所关联的order,可将代码改为如下:
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExcludes(new String[]{"orders"};  // 不序列化order
JSONArray jsonArray = JSONArray.fromObject(customers, jsonConfig);
ServletActionContext.getResponse().getWriter().print(jsonArray.toString());
使用火狐看到的结果如下:

如果也想序列化出customer关联的order但又解决双向关联的死循环问题,代码则如下:
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExcludes(new String[]{"customer"};  // 序列化order,并阻止order中的customer序列化
JSONArray jsonArray = JSONArray.fromObject(customers, jsonConfig);
ServletActionContext.getResponse().getWriter().print(jsonArray.toString());
使用火狐看到的结果如下:

除了使用 JsonLib 外,也可以使用FlexJson,使用 FlexJson比使用JsonLib更灵活(导入flexjson.jar)
JSONSerializer jsonSerializer = new JSONSerializer();
String result = jsonSerializer.serialize(customers);  // 默认只会序列化当前对象,关联的order不会被序列化
String result = jsonSerializer.deepSerialize(customers);  // 深度序列化,关联的对象也会被序列化(不会死循环)










你可能感兴趣的:(java,json,Ajax)