繁体   English   中英

Spring MVC应用程序中具有@JsonIdentityInfo的杰克逊ObjectMapper中的奇怪行为

[英]Strange behaviour in jackson ObjectMapper in Spring MVC application with @JsonIdentityInfo

我对当前在Spring MVC应用程序中看到的那些东西有些困惑,我希望有人可以告诉我我们做错了什么。 由于google没有为我提供答案,因此我确定我们做错了。

我们有一个简单的Spring 4.1.5.RELEASE应用程序。 没什么特别要提的。 有一个MappingJackson2HttpMessageConverter配置为通过Jackson ObjectMapper将JSON传递给RestControllers中的客户端。

通过杰克逊序列化的所有实体在tpe级别上具有以下注释

@JsonIdentityInfo(generator = IntSequenceGenerator.class, property = "@jsonObjectId")

现在奇怪的部分是:

有一个spring集成测试,它执行以下操作(objectMapper从Web应用程序上下文中自动连线,它是转换请求付款的同一实例)

objectMapper.writeValueAsString(dummy) // generate json from dummy object
mockMvc.perform(post(...)) // make a post request with JSON payload generated
evaluate reponse

可以执行一次测试。 如果我复制该测试用例并执行两次,那么我会从服务器返回400,说IllegalArgumentExecption->已经有POJO用作id ...问题可以在现实应用程序中重现,因此这似乎不是测试问题。

我发现,在序列化过程中,每次需要序列化对象时,都会创建负责生成“ jsonObjectId”属性的IntSequenceGenerator。 好的,到目前为止。 但是对应的对应对象,在我们的案例中,杰克逊使用的默认SimpleObjectIdResolver始终是同一实例。 因此,第二个服务器请求(第二个反序列化过程)在SimpleObjectIdResolver中导致该异常。

如果有人能给我一个提示,我将非常感谢,我们正在做错什么...

忘了提及:使用了Jackson-Core 2.4.1。 现在,我们已升级至杰克逊2.7.0版,并且每次反序列化都将重新创建SimpleObjectIdResolver。 在2.7.0之前,这似乎是杰克逊的一个错误。

编辑:我能够将问题减少到以下小型测试:

public class DummyTest {

private Dummy dummy = new Dummy();

@Before
public void setUp() {
    dummy.setFoo("Foo");
}

@Test
public void testApp() throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    String dummyAsJsonString = mapper.writeValueAsString(dummy);

    mapper.readValue(dummyAsJsonString, Dummy.class);
    mapper.readValue(dummyAsJsonString, Dummy.class);
}
}

其中Dummy.class定义为

@JsonIdentityInfo(generator = IntSequenceGenerator.class, property = "@jsonObjectId")
public class Dummy {

private String foo;

public String getFoo() {
    return foo;
}

public void setFoo(String foo) {
    this.foo = foo;
}

}

在杰克逊2.4.1中执行时,您将获得一个IllegalStateException。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM