【问题标题】:How to deserialize JSON string using standard setters如何使用标准设置器反序列化 JSON 字符串
【发布时间】:2014-10-14 00:38:57
【问题描述】:

我正在使用 jackson-core、databind、annotations 2.3.3 jar。我有以下简单的类

public class ClassA {
    private int value;

    public int getValue() {
        return this.value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

下面是尝试将 JSON 字符串反序列化为对象的代码:

import com.fasterxml.jackson.databind.ObjectMapper;

...

final ObjectMapper objectMapper = new ObjectMapper();
ClassA request = objectMapper.readValue("{\"Value\": 1}", ClassA.class);

但我收到以下错误: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段“Value”(ClassA 类),未标记为可忽略(一个已知属性:“value”]) 在 [来源:java.io.StringReader@3bff5976; line: 1, column: 12] (通过引用链: ClassA["Value"])

如果我将 JSON 字符串更改为小写,那么它可以工作。我认为杰克逊可以通过遵循 setter 约定将值映射到 setter。我知道我可以将 JsonProperty 注释添加到 ClassA 以使其工作,但在我的情况下我无法修改 ClassA。

我还尝试在调用 readValue 之前显式启用以下映射功能,但仍然出现相同的错误:

import com.fasterxml.jackson.databind.MapperFeature;

...

objectMapper.enable(MapperFeature.AUTO_DETECT_GETTERS);
objectMapper.enable(MapperFeature.AUTO_DETECT_SETTERS);

我怎样才能让 Jackson 绑定到标准 getter/setter(getXxx 和 setXxx)而不为被绑定的类指定注释?

谢谢!

【问题讨论】:

  • 我认为这是因为您的 JSON 字符串是 Value 而不是 value。你的 JSON 属性会像这样大写吗?

标签: java json serialization jackson


【解决方案1】:

看起来这是因为 Jackson 提供的默认 PropertyNamingStrategy。来自documentation

在没有注册自定义策略的情况下,默认 Java 属性 使用命名策略,保留字段名称,并删除 set/get/is 方法的前缀(以及小写首字母) 大写字符序列)。

映射器默认使用 Java 默认属性命名策略。如果您的 JSON 属性是 Pascal Case(不确定,因为您只提供了 1 个属性),那么您可以为映射器提供 PascalCaseStrategy

final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategy.PascalCaseStrategy());
ClassA request = objectMapper.readValue("{\"Value\": 1}", ClassA.class);

【讨论】:

  • 使用 PropertyNamingStrategy 对我有用,谢谢!
【解决方案2】:

Jackson 遵循 bean 命名约定。

我知道我可以将JsonProperty 注释添加到ClassA 以使其正常工作,但在我的情况下我无法修改ClassA

这就是 mixin 派上用场的地方。创建一个具有与ClassA 相同的方法声明(例如相同的getter)的abstract 类,并使用适当的@JsonProperty 注释对其进行注释。然后,您使用 ObjectMapper 注册 mixin,瞧! ObjectMapper 现在将使用 mixin 类作为模板来序列化和反序列化 ClassA

【讨论】:

  • 感谢您的建议 Sotirios。在我的例子中,我有许多类参与反序列化,为每个类手动创建一个抽象类是相当多的工作。
猜你喜欢
  • 2023-04-01
  • 1970-01-01
  • 2013-01-18
  • 2013-05-07
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多