我有一个简单的POJO:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class StatusPojo {
private String status;
}
当我像这样反序列化简单字符串“asd”(不带引号)时:
StatusPojo pojo = new ObjectMapper().readValue("asd", StatusPojo.class)
我成功创建了一个 StatusPojo 对象,状态字段的值为“asd”,尽管它不是有效的 JSON,并且没有任何地方提到字段名称“status”。
为什么会出现这样的行为以及如何禁用此行为并让对象映射器抛出异常?
您的 POJO 有
@AllArgsConstructor
(可能是因为 @Builder
),然后会生成如下内容:
public StatusPojo(String status) {
this.status = status;
}
当 ObjectMapper 反序列化纯字符串时,它使用该构造函数来创建对象。
如果您向 pojo 添加了一些其他属性,例如:
private String noAsdPlease;
会有一个例外,因为ObjectMapper找不到创建者,就不会有上面提到的构造函数,而是有两个String参数。
快速浏览一下
DeserializationFeature
没有这样一种功能,即禁用对纯字符串使用一个字符串参数构造函数。
使用更多字段,删除
@Builder
和 @AllArgsConstructor
可能会解决您的问题,但如果您无法更改这些字段,则可能没有其他选择。
有一种方法可以改变这种行为。我认为它应该是默认选项。
您可以将
ConstructorDetector
设置为 ConstructorDetector.USE_PROPERTIES_BASED
ObjectMapper objectMapper = JsonMapper.builder().constructorDetector(ConstructorDetector.USE_PROPERTIES_BASED).build();
或者如果您使用 Spring Boot 那么您可以简单地启用它:
spring.jackson.constructor-detector=USE_PROPERTIES_BASED
然后它将适用于您的对象,因为它会尝试将属性与您的构造函数匹配。