【问题标题】:How does Jackson @JsonProperty() work when used to annotate private fields?Jackson @JsonProperty() 在用于注释私有字段时如何工作?
【发布时间】:2020-08-14 21:25:16
【问题描述】:

具体来说,我想知道在反序列化对象时,反序列化器如何设置私有字段?考虑这样的示例类:

public class MyClass {
    @JsonProperty( "My String" );
    private String myString;
}

如果这是使用 objectMapper.readValue(json, MyClass.class); 反序列化的,如果结果对象被标记为 private,如何设置此字段?

【问题讨论】:

标签: java json jackson deserialization


【解决方案1】:

在通过反射读取或写入值之前调用 Field.setAccessible(true) 可以解决问题。

详见对应的javadoc:https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-

但要小心使用 ;-)

【讨论】:

    【解决方案2】:

    不少框架允许使用Field.setAccessible(true) 以这种方式访问​​私有字段。它允许应用程序忽略 Java 语言可见性规则(即私有)并通过反射 API Field 类的实例读取或更改值。

    在这个问题中可以找到更多信息: Java reflection - impact of setAccessible(true)

    【讨论】:

      【解决方案3】:

      简短的回答是它通常不能。我们使用 lombok 为变量生成 getter/setter,但您当然可以编写自己的。 Jackson 与您的主代码具有相同的可见性,因此如果没有一些公共 getter/setter 或像这样配置对象映射器,则无法映射私有字段...objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

      它也无法正常序列化。您可以在班级级别使用 Lombok @Getter@Setter,以便 Jackson 可以使用 myString,或者将 @JsonAutoDetect(fieldVisibility = Visibility.ANY) 放在班级级别,如下所示。

      @JsonAutoDetect(fieldVisibility = Visibility.ANY)
      public class MyClass {
          @JsonProperty( "My String" );
          private String myString;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-25
        • 2012-06-11
        • 2018-06-07
        • 2018-01-23
        • 2014-06-02
        • 2012-12-14
        • 1970-01-01
        • 2015-05-31
        相关资源
        最近更新 更多