`
jlj008
  • 浏览: 96723 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

关于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
分享到:
评论

相关推荐

    sojo-optional-0.5.0

    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 ...

    hcatalog-0.5.0

    4. **数据输入/输出层**:HCatalog为MapReduce作业提供了一种标准化的输入/输出接口,使得开发者可以专注于编写业务逻辑,而不是处理数据读写的细节。 5. **Web服务接口**:HCatalog提供了RESTful Web服务接口,...

    projeto_zero:网站sojo o jogo Horizo​​n Zero Dawn

    在该项目中,我们可以推测开发者可能想要构建一个关于这款游戏的信息平台,可能是粉丝站点、攻略集、社区论坛或者是游戏相关新闻的发布站。 提到的标签"HTML"表明这个项目主要基于HTML语言进行开发。HTML...

    300444_双杰电气上市招股说明书.pdf

    - **名称**:北京双杰电气股份有限公司(Beijing SOJO Electric Co., Ltd.) - **地址**:北京市海淀区上地三街9号D座1111室 - **业务范围**:虽然具体业务范围没有详细列出,但从名称可以看出该公司主要业务可能...

    FisherGrid使用说明

    依赖组件包括Jquery、Flexigrid、Digester、Freemarker、Sojo、Log4j、Beanutils、Collections、Hsqldb(示例运行需要)和Hibernate等,这些组件共同确保了FisherGrid的强大功能和稳定运行。 总的来说,FisherGrid...

Global site tag (gtag.js) - Google Analytics