关于sojo输出json中出现~unique-id~字样的问题

问题:在项目中,问题的表现如下,使用SojoJsonStringWriter,当需要序列化一个对象成json格式时
class Result {
List<Broadcast> broadcasts;
...
}
class Broadcast {
List<Presenter> presenters;
...
}

如果result中的多个broadcast共用了同一个presenter,输出结果中,第一个broadcast中的presenter正常,而第2、3个presenter显示为~unique-id~1。
原因:
Spring集成jsonview的时候,其中有以下两种方式较为常用,
SojoJsonStringWriter:必须要有set/get方法,对boolean;is不会序列化,只能用get替代;对共用对象的多次解析会出现~unique-id~(可能是因为Hibernate持久中的延迟加载的缘故)
JsonlibJsonStringWriter:功能上没有前者强,如类型需要自己转化,但可以通过定制JsonConfig来实现;不会出现对共用对象的多次解析会出现~unique-id~
解决方案:
使用JsonlibJsonStringWriter,在views.xml中新增
<bean name="jsonlibView" class="org.springframework.web.servlet.view.json.JsonView">
<property name="encoding" value="UTF-8" />
<property name="contentType" value="application/json" />
<property name="jsonWriter" ref="jsonlibJsonStringWriter" />
<property name="jsonErrors">
<list>
<ref bean="statusError" />
<ref bean="modelflagError" />
</list>
</property>
</bean>
<bean name="jsonlibJsonStringWriter" class="org.springframework.web.servlet.view.json.writer.jsonlib.JsonlibJsonStringWriter">
<property name="convertAllMapValues" value="true" />
<property name="enableJsonConfigSupport" value="true" />
</bean>


此时,直接使用,可能会出现异常:net.sf.json.JSONException: java.lang.NoSuchMethodException: Property 'delegate' has no getter method
这是因为实体对象用的是Hibernate的延迟加载,可以通过以下方式解决:
public class HibernateJsonBeanProcessor implements JsonBeanProcessor {
public JSONObject processBean(Object obj, JsonConfig jsonConfig) {
return new JSONObject();
}
}
public class HibernateJsonBeanProcessorMatcher extends JsonBeanProcessorMatcher {
private final Log logger = LogFactory.getLog(HibernateJsonBeanProcessorMatcher.class);
@SuppressWarnings("unchecked")
@Override
public Object getMatch(Class target, Set set) {
if (target.getName().contains("$$EnhancerByCGLIB$$")) {
logger.warn("Found Lazy-References in Hibernate object " + target.getName());
return org.hibernate.proxy.HibernateProxy.class;
}
return DEFAULT.getMatch(target, set);
}
}
public class HibernateJsonlibJsonWriterConfiguratorTemplate extends JsonlibJsonWriterConfiguratorTemplate {
@Override
public JsonConfig getJsonConfig() {
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.registerJsonBeanProcessor(HibernateProxy.class, new HibernateJsonBeanProcessor());
jsonConfig.setJsonBeanProcessorMatcher(new HibernateJsonBeanProcessorMatcher());
return jsonConfig;
}
}

在controller的方法返回mav之前,执行以下代码进行注册config
JsonWriterConfiguratorTemplateRegistry registry = JsonWriterConfiguratorTemplateRegistry.load(request);
registry.registerConfiguratorTemplate(new HibernateJsonlibJsonWriterConfiguratorTemplate());


此时调试,可能会出现另一个异常:net.sf.json.JSONException: There is a cycle in the hierarchy
这可能是Bean对象里有循环调用的属性,解决办法是,增加循环应对的策略,
config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
或者设置过滤字段,将有可能循环的属性过滤掉,config.setExcludes(new String[])
这里还可以增加别的功能,如
config.setIgnoreDefaultExcludes(false);
config.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor("MM/dd/yyyy"));
...

至此,问题解决。
参考:
http://spring-json.sourceforge.net/binding.html
http://www.cnblogs.com/yueue/archive/2010/02/23/1672059.html
http://pipe.iteye.com/blog/224564
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值