英文:
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-
但要小心使用
英文:
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
答案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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论