【问题标题】:Jackson failing to deserialize simple JSON杰克逊未能反序列化简单的 JSON
【发布时间】:2021-10-08 03:12:58
【问题描述】:

我正在使用 Lombok,@Annotations 为我创建了 getter、setter 和构造函数。我有许多其他的类,杰克逊很容易反序列化。这是我试图反序列化的对象:

@Value
@Builder
public class RecipeListRemoveDTO {
    int recipeListId;
}

在以下 Controller 方法中使用:

@DeleteMapping(path="/deleteRecipeListFromUser")
public @ResponseBody String deleteRecipeListFromUser(@RequestBody RecipeListRemoveDTO recipeListRemoveDTO) {
    return recipeListService.removeRecipeListFromUser(recipeListRemoveDTO);
}

还有我要发送的 JSON:

{
    "recipeListId": 2
}

但我收到错误消息:

"message": "JSON parse error: Cannot construct instance of com.prepchef.backend.models.dto.RecipeListRemoveDTO (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of com.prepchef.backend.models.dto.RecipeListRemoveDTO (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (PushbackInputStream); line: 2, column: 5]"

有人知道为什么会这样吗?

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    Jackson 不知道它应该使用 Lombok 生成的构建器。 可能最简单的解决方案是用 Lombok's @Jacksonized annotation 注释你的类(从 Lombok 开始可用 1.18.14)。

    @Value
    @Builder
    @Jacksonized
    public class RecipeListRemoveDTO {
        int recipeListId;
    }
    

    在后台 @Jacksonized 注释会导致 Lombok 做以下事情(这样你就不需要做这些 手动):

    • 它添加了@JsonDeserialize(builder=RecipeListRemoveDTO.RecipeListRemoveDTOBuilder.class) 到你的班级,让杰克逊知道它应该使用 反序列化的构建器。
    • 它将@JsonPOJOBuilder(withPrefix="")添加到构建器类中, 让杰克逊知道 builder 方法有一个名字 不是以with开头的。

    【讨论】:

    • 这对我有用。其他解决方案没有。但是,这很奇怪,因为我有大约 20 个类似的 DTO 对象,Jackson 只需一个 Value 和 Builder 注释就可以完全反序列化所有这些对象。可能有人知道为什么这个案例需要它而其他案例不需要吗?
    【解决方案2】:

    这不起作用的原因是当您将@Value@Builder 结合使用时,不会生成public 构造函数:

    此外,任何显式构造函数,无论参数列表如何,都意味着 lombok 不会生成构造函数。如果您确实希望 lombok 生成全参数构造函数,请将 @AllArgsConstructor 添加到类中。

    将@Builder 应用到一个类就好像你添加了@AllArgsConstructor(access = AccessLevel.PACKAGE) 到类

    因此,综上所述,如果您希望保持@Value 提供的不变性,在这种情况下您还需要添加@AllArgsConstructor

    【讨论】:

    • 不幸的是,在添加 @AllArgsConstructor 并修改其他方法后,我仍然收到相同的错误。
    【解决方案3】:

    当您使用 Lomboks @Value 注释时不会生成设置器,这就是您在代码中遇到异常的原因。相反,您应该使用 @Data 注释。

    【讨论】:

    • 我仍然遇到同样的错误。
    【解决方案4】:
    @Value
    @Builder
    @JsonDeserializer(builder = RecipeListRemoveDTO.RecipeListRemoveDTOBuilder.class)
    public final class RecipeListRemoveDTO {
        int recipeListId;
        
        @JsonPOJOBuilder(withPrefix = "")
        public static final class RecipeListRemoveDTOBuilder {}
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      • 2014-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-20
      • 1970-01-01
      相关资源
      最近更新 更多