Jackson @JsonProperty()在对私有字段进行注解时是如何工作的?

huangapple go评论78阅读模式
英文:

How does Jackson @JsonProperty() work when used to annotate private fields?

问题

具体而言,我想知道在反序列化对象时,反序列化程序如何设置私有字段?想象一个类似这样的示例类:

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

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

英文:

Specifically I am wondering how when deserializing an object the deserializer could set a private field? Thinking of an example class like this:

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

If this is deserialized using objectMapper.readValue(json, MyClass.class); how does the resulting object have this field set if it is marked as private?

答案1

得分: 4

简短的回答是通常情况下无法实现。我们使用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;
}
英文:

The short answer is that it can't normally. We use lombok to generate the getter/setter for the variables, but you can of course write your own. Jackson has the same visibility as your main code does, so a private field cannot be mapped without some public getter/setter OR configuring the object mapper like so... objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);.

It wouldn't be able to serialize that either normally. You can use Lombok @Getter and @Setter on the class level so Jackson can work with myString, or put @JsonAutoDetect(fieldVisibility = Visibility.ANY) at the class level like below.

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

答案2

得分: 3

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

详细信息请参阅相应的 Java 文档:https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-

但要小心使用 Jackson @JsonProperty()在对私有字段进行注解时是如何工作的?

英文:

Calling Field.setAccessible(true) before reading or writing a value through reflection does the trick here.

For details see the corresponding javadoc: https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-

But use with care Jackson @JsonProperty()在对私有字段进行注解时是如何工作的?

答案3

得分: 2

相当多的框架允许通过使用 Field.setAccessible(true) 来访问私有字段。它允许应用程序忽略Java语言的可见性规则(即private),并通过反射API的Field类的实例来读取或修改该值。

在这个问题中可以找到更多信息:
https://stackoverflow.com/questions/10638826/java-reflection-impact-of-setaccessibletrue

英文:

Quite a few frameworks allow access to private fields in this manner by using Field.setAccessible(true). It allows the application to ignore the Java language visibility rules (i.e. private) and read or change the value via an instance of the Reflection API Field class.

A little more can be found in this question:
https://stackoverflow.com/questions/10638826/java-reflection-impact-of-setaccessibletrue

huangapple
  • 本文由 发表于 2020年8月15日 05:25:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/63420195.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定