【问题标题】:jackson spring controller serializationjackson spring控制器序列化
【发布时间】:2014-05-06 15:44:07
【问题描述】:

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

我在模型中使用了 jackson2 注释 (com.fasterxml.jackson.annotation),并且我(猜测)spring rest 控制器在序列化请求的对象时应该使用 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(我不确定为什么要添加它,因为我只是从其他开发人员那里继承了代码)。

请注意,据我所知,spring3.2 默认应该使用 jackson2。 这大部分工作正常,但是我有一个序列化问题,它只发生在特定的服务/控制器上。我有一个定义父对象的对象,包含与子对象相同的对象。这导致了一个序列化循环,该循环以服务器端的异常结束:

[...]
        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 发送到客户端。

这是控制器代码:

@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 时可能会忽略它们,这(我认为)可能会导致循环问题。

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

【问题讨论】:

  • 请将完整的堆栈跟踪和您的控制器代码添加到您的问题中。
  • 你确定myProj.util.HibernateAwareObjectMapper扩展了fasterxml ObjectMapper吗?
  • @Codo,添加了控制器代码,关于完整的堆栈跟踪我不知道如何获取它,因为它被打印到控制台并被截断(而且我是一个相对 n00b spring/log4j用户)。
  • @JBCP,是的,我很确定,扩展了我的答案以显示其代码。
  • 从您的 pom 中删除您的 jackson 1 依赖项并仅放置 jackson 2 依赖项,然后应该可以工作。

标签: java json spring spring-mvc jackson


【解决方案1】:

嗯,原来问题是由于控制器代码中缺少@ResponseBody 注释。

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

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

在多次尝试挖掘 Spring 代码的徒劳尝试之后,我将此控制器代码与未显示问题的类似控制器的代码进行比较,从而发现了问题。

感谢大家的回答!

【讨论】:

    【解决方案2】:

    Jackson2 在类路径上时,Spring 会自动配置MappingJackson2HttpMessageConverter。但是,您可以通过定义自己的 MappingJackson2HttpMessageConverter 类型的 bean 来覆盖此行为。首先,检查它是否是您的 bean 用于序列化(例如通过调试)。然后检查它的配置。似乎ObjectMapper 的 Hibernate 扩展的构造函数没有调用super(),这意味着缺少默认的SerializerProviderBeanSerializerFactory 的配置。详情请见http://fasterxml.github.io/jackson-databind/javadoc/2.0.0/com/fasterxml/jackson/databind/ObjectMapper.html

    【讨论】:

      猜你喜欢
      • 2017-12-19
      • 2016-10-17
      • 2021-03-30
      • 2017-07-21
      • 2023-04-10
      • 2011-12-02
      • 1970-01-01
      • 2019-04-03
      • 1970-01-01
      相关资源
      最近更新 更多