问题:在项目中,问题的表现如下,使用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
分享到:
相关推荐
Download sojo-optional-0.5.0.jar META-INF/MANIFEST.MF net.sf.sojo.common.CompareResult.class net.sf.sojo.common.GenericComparator.class net.sf.sojo.common.IterateableUtil.class ...
4. **数据输入/输出层**:HCatalog为MapReduce作业提供了一种标准化的输入/输出接口,使得开发者可以专注于编写业务逻辑,而不是处理数据读写的细节。 5. **Web服务接口**:HCatalog提供了RESTful Web服务接口,...
在该项目中,我们可以推测开发者可能想要构建一个关于这款游戏的信息平台,可能是粉丝站点、攻略集、社区论坛或者是游戏相关新闻的发布站。 提到的标签"HTML"表明这个项目主要基于HTML语言进行开发。HTML...
- **名称**:北京双杰电气股份有限公司(Beijing SOJO Electric Co., Ltd.) - **地址**:北京市海淀区上地三街9号D座1111室 - **业务范围**:虽然具体业务范围没有详细列出,但从名称可以看出该公司主要业务可能...
依赖组件包括Jquery、Flexigrid、Digester、Freemarker、Sojo、Log4j、Beanutils、Collections、Hsqldb(示例运行需要)和Hibernate等,这些组件共同确保了FisherGrid的强大功能和稳定运行。 总的来说,FisherGrid...