Json-lib 与 hibernate 共同使用的问题

hibernate使用CGLIB把POJO的domain对象动态代理,实现它的魔法,但是给JSON的序列化带来了麻烦,因为JSON无法对lazy的属性进行序列化。有以下的四个方法可以解决hibernate的序列化问题

  1. domain类实现JSONString接口
  2. 建立JsonConfig实例,并配置属性排除列表
  3. 用属性过滤器
  4. 写一个自定义的JsonBeanProcessor

1. 实现JSONString接口是侵入性最强的方法

Java代码  

  1. public class Person implements JSONString {
  2. private String name;
  3. private String lastname;
  4. private Address address;
  5. // getters & setters
  6. public String toJSONString() {
  7. return "{name:‘"+name+"‘,lastname:‘"+lastname+"‘}";
  8. }
  9. }

2.第二种方法通过jsonconfig实例,对包含和需要排除的属性进行方便添加删除

Java代码  

  1. public class Person {
  2. private String name;
  3. private String lastname;
  4. private Address address;
  5. // getters & setters
  6. }
  7. JsonConfig jsonConfig = new JsonConfig();
  8. jsonConfig.setExclusions( new String[]{ "address" } );
  9. Person bean = /* initialize */;
  10. JSON json = JSONSerializer.toJSON( bean, jsonConfig );

注意:这种方法不区分目标类,就是说如果有2个bean当中都存在“address”属性,那么采用这种方法,这两个bean中的address属性都将被排除

3. 使用propertyFilter可以允许同时对需要排除的属性和类进行控制,这种控制还可以是双向的,也可以应用到json字符串到java对象

Java代码  

  1. public class Person {
  2. private String name;
  3. private String lastname;
  4. private Address address;
  5. // getters & setters
  6. }
  7. JsonConfig jsonConfig = new JsonConfig();
  8. jsonConfig.setJsonPropertyFilter( new PropertyFilter(){
  9. public boolean apply( Object source, String name, Object value ){
  10. // return true to skip name
  11. return source instanceof Person && name.equals("address");
  12. }
  13. });
  14. Person bean = /* initialize */;
  15. JSON json = JSONSerializer.toJSON( bean, jsonConfig )

4. 最后来看JsonBeanProcessor,这种方式和实现JsonString很类似,返回一个代表原来的domain类的合法JSONOBJECT

Java代码  

  1. public class Person {
  2. private String name;
  3. private String lastname;
  4. private Address address;
  5. // getters & setters
  6. }
  7. JsonConfig jsonConfig = new JsonConfig();
  8. jsonConfig.registerJsonBeanProcessor( Person.class,
  9. new JsonBeanProcessor(){
  10. public JSONObject processBean( Object bean, JsonConfig jsonConfig ){
  11. if( !(bean instanceof Person) ){
  12. return new JSONObject(true);
  13. }
  14. Person person = (Person) bean;
  15. return new JSONObject()
  16. .element( "name", person.getName() )
  17. .element( "lastname", person.getLastname() );
  18. }
  19. });
  20. Person bean = /* initialize */;
  21. JSON json = JSONSerializer.toJSON( bean, jsonConfig );

And it is here with JsonBeanProcessors where we encounter the second gotcha related to CGlib. As you noticed we registered the processor using Person as target class, but Hibernate returns a Proxy that is not exactly a Person but a subclass (if possible) of Person. The default matching algorithm used by Json-lib will try to match the exact class (using equals), meaning that your processor will not be called when you expect it to be,this is why JsonBeanProcessorMatcher was introduced, now you are be able to write the following code

<textarea class="java:nocontrols:nogutter" cols="80" rows="34" name="srccode">public class Person {   private String name;   private String lastname;   private Address address;   // getters & setters } JsonConfig jsonConfig = new JsonConfig(); jsonConfig.registerJsonBeanProcessor( Person.class,   new JsonBeanProcessor(){      public JSONObject processBean( Object bean, JsonConfig jsonConfig ){         if( !(bean instanceof Person) ){            return new JSONObject(true);         }         Person person = (Person) bean;         return new JSONObject()            .element( "name", person.getName() )            .element( "lastname", person.getLastname() );      } }); jsonConfig.registerJsonBeanProcessorMatcher(   new JsonBeanProcessorMatcher(){      public Object getMatch( Class target, Set/*<Class>*/ matches ){         for( Object match : matches ){            if( ((Class)match).isAssignableFrom(target) ){               return match;            }         }         return null;      } }); Person bean = /* initialize */; JSON json = JSONSerializer.toJSON( bean, jsonConfig );</textarea>

I hope these examples help dispel some doubts, in any case please feel free to drop by Json-lib‘s forum and mailing lists.

时间: 2024-11-30 12:57:27

Json-lib 与 hibernate 共同使用的问题的相关文章

JSON lib 里JsonConfig详解

一,setCycleDetectionStrategy 防止自包含 /** * 这里测试如果含有自包含的时候需要CycleDetectionStrategy */ public static void testCycleObject() { CycleObject object = new CycleObject(); object.setMemberId("yajuntest"); object.setSex("male"); JsonConfig jsonCon

json lib 2.4及其依赖包下载

下载文件地址:https://files.cnblogs.com/files/xiandedanteng/json-lib-2.4%26dependencies_jars.rar 它包括 commons-beanutils-1.9.3.jar commons-collections-3.2.jar commons-lang-2.3.jar commons-logging-1.2.jar ezmorph-1.0.6.jar json-lib-2.4-jdk15.jar 这些库可以满足转化Java对

json+hibernate死循环问题的一点见解

[问题]如题所示,在我们使用hibernate框架而又需要将对象转化为json的时候,如果配置了双向的关联关系,就会出现这个死循环问题 异常信息: [原因]为什么会这样呢?原因在于你要转化的对象里配置了对另外一个对象的关联,而那个对象里又配置了对你这个对象的关联.比如我的两个类叫做Shop(商店)和Staff(员工),一个商店可以有多个员工,所以我给这两个对象配置了双向的一对多和多对一的关联关系.这时候问题就出现了,JSON lib在把shop对象转化为json字符串的时候,发现shop里有个S

Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加

package com.aherp.framework.util; import java.lang.reflect.Array;import java.lang.reflect.Method;import java.util.Collection;import java.util.Iterator;import java.util.Map; import org.json.JSONArray;import org.json.JSONException;import org.json.JSONO

Spring+Jersey+JPA+Hibernate+MySQL实现CRUD操作案例

本文承接我的另一篇博文:Spring+Jersey+Hibernate+MySQL+HTML实现用户信息增删改查案例(附Jersey单元测试),主要更改内容如下: Spring配置文件applicationContext中原先使用的是Hibernate,现在改为Hibernate对JPA的支持: 增加了C3P0连接池: 修改了Dao操作实现,改为Spring接管的JPA实现. 如果读者想详细查看Spring整合Jersey与前端交互可以点击上述连接.本文主要介绍以上三处修改内容,并且使用Jers

还在用Json完成Ajax,改用Beetl吧(上)

浏览器通过AJAX,服务器返回json数据,无刷新的更新视图的这种模式在WEB开发中我已经用了很长时间了,记得最早是08年的时候用的,当时传递JSON数据让我眼前一亮.这种方式是只需要采用工具包将模型序列化成json格式就行,js UI库总能识别这种格式,轻易的生成新的视图片段. 然而时过境迁.这种传递AJAX JSON方式渐渐有了新的问题. JSON序列化库无法完美的序列化模型对象.序列化库总期望输入一个Object,但实际上前端有可能需要多个Object,这样,你不得不再创建一个序列化专用的

json库的编译方法和vs2010中导入第三方库的方法

一.去相应官网下载json.cpp文件 Jsoncpp下载:https://sourceforge.net/projects/jsoncpp/    版本为v0.5.0 最新版本在:https://github.com/open-source-parsers/jsoncpp 二.编译链接成库文件 1)解压下载的json包,得到jsoncpp-src-0.5.0文件,打开jsoncpp-src-0.5.0\makefiles\vs71\jsoncpp.sln 2)转换项目为vs2010格式,并将模

spring,hibernate,struts整合

SSH整合: Spring与Hibernate整合 Spring与Struts整合 整合步骤:---------------------------------------------->本人使用的是struts2.3.4.1   hibernate3.6.0  spring3.2.5 1.导入jar文件 1)struts jar文件-->如何找? -->去源码包中struts-2.3.4.1\apps\struts-blank.war -->使用压缩文件打开struts-blan

Hibernate目录结构以及环境搭建

上篇博客,概述了一下Hibernate,今天这篇继续说说Hibernate包含的各个包的含义,以及对hibernate环境的搭建. 一.hibernate目录解析 下载好一个hibernate包,解压看到里边有若干个文件夹,这些东东是都是什么,有神马作用呢?看下图: 上图是捡着重要的目录给重新命名了. 由上至下依次表示: API 文档--doc:操作的hibernate的手册, 映射文件实例--eg:里边包含的就是hbm文件的书写实例, 配置文件实例--etc:包含hibernate配置文件cf

搭建hibernate环境

Hibernate概述什么是框架1 写程序,使用框架之后,帮我们实现一部分功能,使用框架好处,少写一部分代码实现功能 什么是hibernate框架(重点)1 hibernate框架应用在javaee三层结构中 dao层框架 2 在dao层里面做对数据库crud操作,使用hibernate实现crud操作,hibernate底层代码就是jdbc,hibernate对jdbc进行封装,使用hibernate好处,不需要写复杂jdbc代码了,不需要写sql语句实现 3 hibernate开源的轻量级的