如何防止 ObjectMapper 成功将纯字符串反序列化为 Object?

Posted

技术标签:

【中文标题】如何防止 ObjectMapper 成功将纯字符串反序列化为 Object?【英文标题】:How to prevent ObjectMapper de-serializing plain string to Object successfully? 【发布时间】:2021-03-09 11:25:18 【问题描述】:

我有一个简单的 POJO:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class StatusPojo 

  private String status;


当我像这样反序列化简单字符串“asd”(不带引号)时:

StatusPojo pojo = new ObjectMapper().readValue("asd", StatusPojo.class)

我正在成功创建一个 StatusPojo 对象,状态字段的值为“asd”,尽管它不是有效的 JSON,并且没有地方提到字段名称“status”。

为什么会有这样的行为以及如何禁用这种行为并让对象映射器抛出异常?

【问题讨论】:

"asd" 是有效的 json,payload 不一定要有对象。毕竟可以反序列化成一个简单的 String 对象。 Jackson 可以将其反序列化为具有单个 String 属性的对象这一事实并不让我感到惊讶,使用 Jackson 的主要原因是它的灵活性和可配置性。不过,我没有发现配置切换可以这么快地禁用此特定行为。 它是和"asd"一起工作还是应该是"\"asd\"" @Gimby asd 不是有效的 json。 "asd" @fps 问题中没有任何内容表明未引用数据。 【参考方案1】:

您的 POJO 有 @AllArgsConstructor(可能是因为 @Builder)然后生成如下内容:

public StatusPojo(String status) 
    this.status = status;

当 ObjectMapper 然后反序列化纯字符串时,它使用该构造函数来创建对象。

如果您在 pojo 中添加了一些其他属性,例如:

private String noAsdPlease;

会有一个例外,因为ObjectMapper找不到创建者,所以不会有上面提到的构造函数,而是有两个String参数。

一目了然DeserializationFeature 没有这样的功能,即禁止对纯字符串使用一个字符串 arg 构造函数。

使用更多字段,删除 @Builder@AllArgsConstructor 可能会解决您的问题,但如果您无法更改这些字段,则可能没有其他选项。

【讨论】:

以上是关于如何防止 ObjectMapper 成功将纯字符串反序列化为 Object?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NestJS 将纯文本作为我的请求正文传递?

如何使用 Alamofire/ObjectMapper 返回嵌入在字典中的 JSON 字符串?

Swift:如何将带有 Alamofilre 或 SwiftyJSON 的 JSON 字符串转换为 ObjectMapper?

powershell 将纯文本字符串转换为安全字符串

将纯字符串转换为 JSON 并返回 Swift

Jackson ObjectMapper 如何将 byte[] 传输到 String 以及如何在没有对象类的情况下翻译它?