java - Jackson Spring Controller 序列化

标签 java json spring spring-mvc jackson

我有一个 Java Spring 3.2 + Hibernate 项目。

我在模型中使用了 jackson2 注释(com.fasterxml.jackson.annotation),并且我(猜测)Spring Rest Controller 在序列化请求的对象时应该使用 jackson2 (又名 com.fasterxml.jackson)。

我使用以下方式配置了应用程序:

        <!-- Use the HibernateAware mapper instead of the default -->
        <bean
            class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="myProj.util.HibernateAwareObjectMapper">
                    <property name="serializationInclusion">
                        <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
                    </property>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>

HibernateAwareObjectMapper 的定义方式如下:

package myProj.util;

import com.fasterxml.jackson.databind.ObjectMapper;

public class HibernateAwareObjectMapper extends ObjectMapper {
private static final long serialVersionUID = -5002954669679467811L;

public HibernateAwareObjectMapper() {
        Hibernate4Module hbm = new Hibernate4Module();
        hbm.enable(Hibernate4Module.Feature.FORCE_LAZY_LOADING);
        registerModule(hbm);
    }
}

所以我可以声明它扩展了 com.fasterxml ObjectMapper (OTOH,我不确定为什么添加它,因为我只是从其他开发人员继承了代码)。

请注意,据我所知,spring3.2 默认情况下应该使用 jackson2。 这基本上工作正常,但随后我遇到了序列化问题,该问题仅发生在特定服务/ Controller 上。我有一个定义父对象的对象,其中包含与子对象相同的对象。这会导致序列化循环,并以服务器端异常结束:

[...]
        at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
        at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
        at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
        at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
        at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
        at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
        at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
        at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
[...]

并向客户端发送不完整的 JSON。

这是 Controller 代码:

@RequestMapping(value = "/getReleases", method = RequestMethod.POST)
public Map<String, Object> getReleases(@RequestBody Project project) {
    Map<String, Object> subProjectsMap = new HashMap<String, Object>();
    List<Release> releaseList = null;
    try {
        releaseList = jiraService.getReleases(project);
        subProjectsMap.put("success", (releaseList.size() > 0) ? true : false);
        subProjectsMap.put("data", releaseList);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return subProjectsMap;
}

序列化由框架隐式执行。

问题是:为什么 spring 显然使用 org.codehaus.jackson 而不是我所期望的 com.fasterxml.jackson ?请注意,描述序列化对象的模型使用 jackson2 注释(特别是 @JsonBackReference 和 @JsonIgnore),因此在使用 jackson1 时可能会忽略它们,这(我认为)可能会导致循环问题。

经过几个小时的敲头之后,我仍然不知道为什么会发生这种情况。你能提供任何提示吗?

最佳答案

事实证明,问题是由于 Controller 代码中缺少 @ResponseBody 注释造成的。

 @RequestMapping(value = "/getReleases", method = RequestMethod.POST)
 public @ResponseBody Map<String, Object> getReleases(@RequestBody Project project) {
      [...]
 }

添加 @ResponseBody 注释神奇地解决了我的问题。

在多次徒劳地尝试挖掘 Spring 代码之后,我通过将此 Controller 代码与未显示问题的类似 Controller 的代码进行比较(愚蠢的是我之前没有这样做)意识到了问题。

谢谢大家的解答!

关于java - Jackson Spring Controller 序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23499217/

相关文章:

java - 添加到随机数

java - 将错误消息作为 JSON 对象发送

spring - Spring框架如何处理基于XML namespace 的语法来配置Spring组件?

java - Jackson 在 Spring 中没有正确解码 xml

java - 如何使用 JGit API 从父提交中获取树?

java - 如何修改此程序以包含可用于更改此小程序的背景颜色的八种颜色的 JList?

java - 生成自定义 javadoc 时遇到问题; 'cannot find doclet'

java - 仅使用字符串和值解析 JSON 对象

javascript - d3.js 中从 CSV 到 JSON 的转换

java - Swagger UI 导致带有文件和 json 对象的 spring-resources 的 Multipart-FormData 请求失败