杰克逊未能反序列化简单 JSON
Jackson failing to deserialize simple JSON
我正在使用 Lombok,@Annotations 为我创建了 getter、setter 和构造函数。我有许多其他的 类 杰克逊很容易反序列化。这是我要反序列化的对象:
@Value
@Builder
public class RecipeListRemoveDTO {
int recipeListId;
}
在以下控制器方法中使用:
@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]"
有人知道为什么会这样吗?
当您使用 Lomboks @Value annotation that's why you're getting the exception in your code. Instead you should use @Data 注释时,不会生成设置器。
这不起作用的原因是当您使用 @Value
in conjunction with @Builder
时,没有生成 public
构造函数:
Also, any explicit constructor, no matter the arguments list, implies lombok will not generate a constructor. If you do want lombok to generate the all-args constructor, add @AllArgsConstructor to the class.
和
applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE) to the class
因此,总而言之,如果您希望保持 @Value
提供的不变性,在这种情况下您还需要添加 @AllArgsConstructor
.
@Value
@Builder
@JsonDeserializer(builder = RecipeListRemoveDTO.RecipeListRemoveDTOBuilder.class)
public final class RecipeListRemoveDTO {
int recipeListId;
@JsonPOJOBuilder(withPrefix = "")
public static final class RecipeListRemoveDTOBuilder {}
}
Jackson 不知道它应该使用 Lombok 生成的构建器。
可能最简单的解决方案是用 Lombok's @Jacksonized
annotation 注释你的 class (自 Lombok 以来可用
1.18.14).
@Value
@Builder
@Jacksonized
public class RecipeListRemoveDTO {
int recipeListId;
}
在幕后 @Jacksonized
注释导致 Lombok
做以下事情(这样你就不需要做这些
手动):
- 它增加了
@JsonDeserialize(builder=RecipeListRemoveDTO.RecipeListRemoveDTOBuilder.class)
到您的 class,以便 Jackson 知道它应该使用
反序列化的构建器。
- 它将
@JsonPOJOBuilder(withPrefix="")
添加到构建器 class,
这样 Jackson 就知道构建器方法有一个名字
不是以 with
. 开头
我正在使用 Lombok,@Annotations 为我创建了 getter、setter 和构造函数。我有许多其他的 类 杰克逊很容易反序列化。这是我要反序列化的对象:
@Value
@Builder
public class RecipeListRemoveDTO {
int recipeListId;
}
在以下控制器方法中使用:
@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]"
有人知道为什么会这样吗?
当您使用 Lomboks @Value annotation that's why you're getting the exception in your code. Instead you should use @Data 注释时,不会生成设置器。
这不起作用的原因是当您使用 @Value
in conjunction with @Builder
时,没有生成 public
构造函数:
Also, any explicit constructor, no matter the arguments list, implies lombok will not generate a constructor. If you do want lombok to generate the all-args constructor, add @AllArgsConstructor to the class.
和
applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE) to the class
因此,总而言之,如果您希望保持 @Value
提供的不变性,在这种情况下您还需要添加 @AllArgsConstructor
.
@Value
@Builder
@JsonDeserializer(builder = RecipeListRemoveDTO.RecipeListRemoveDTOBuilder.class)
public final class RecipeListRemoveDTO {
int recipeListId;
@JsonPOJOBuilder(withPrefix = "")
public static final class RecipeListRemoveDTOBuilder {}
}
Jackson 不知道它应该使用 Lombok 生成的构建器。
可能最简单的解决方案是用 Lombok's @Jacksonized
annotation 注释你的 class (自 Lombok 以来可用
1.18.14).
@Value
@Builder
@Jacksonized
public class RecipeListRemoveDTO {
int recipeListId;
}
在幕后 @Jacksonized
注释导致 Lombok
做以下事情(这样你就不需要做这些
手动):
- 它增加了
@JsonDeserialize(builder=RecipeListRemoveDTO.RecipeListRemoveDTOBuilder.class)
到您的 class,以便 Jackson 知道它应该使用 反序列化的构建器。 - 它将
@JsonPOJOBuilder(withPrefix="")
添加到构建器 class, 这样 Jackson 就知道构建器方法有一个名字 不是以with
. 开头