我有一个 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/