【问题标题】:Strange behaviour in jackson ObjectMapper in Spring MVC application with @JsonIdentityInfo带有@JsonIdentityInfo的Spring MVC应用程序中jackson ObjectMapper中的奇怪行为
【发布时间】:2016-05-15 09:43:20
【问题描述】:

我对目前在 Spring MVC 应用程序中看到的那些东西有点困惑,我希望有人能告诉我我们做错了什么。由于谷歌没有给我答案,我确定我们错了。

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

所有通过jackson序列化的实体在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 for id ... 问题可以在现实世界的应用程序中重现,所以它似乎没有测试问题。

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

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

【问题讨论】:

    标签: java json spring-mvc jackson objectmapper


    【解决方案1】:

    忘了说:使用的是 Jackson-Core 2.4.1。我们现在升级到 jackson 的 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;
    }
    
    }
    

    使用 jackson 2.4.1 执行它时,您将收到 IllegalStateException

    【讨论】:

    • 您好 Ansgar,我知道 2.7.0 之前的版本在哈希数组和字符串方面存在一些错误,您有跟踪错误吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2016-01-03
    • 2023-03-11
    • 2017-04-23
    • 2020-09-03
    • 2021-01-09
    相关资源
    最近更新 更多