什么时候使用@JsonProperty属性,它用于什么?

这个豆子“状态”:

public class State {


private boolean isSet;


@JsonProperty("isSet")
public boolean isSet() {
return isSet;
}


@JsonProperty("isSet")
public void setSet(boolean isSet) {
this.isSet = isSet;
}


}

通过ajax ' success'回调发送:

        success : function(response) {
if(response.State.isSet){
alert('success called successfully)
}

注释@JsonProperty这里需要吗?使用它的好处是什么? 我想我可以删除这个注释而不会引起任何副作用

阅读https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations上的这个注释,我不知道什么时候需要使用它?

631858 次浏览

这里有一个很好的例子。我使用它来重命名变量,因为JSON来自.Net环境,其中属性以大写字母开头。

public class Parameter {
@JsonProperty("Name")
public String name;
@JsonProperty("Value")
public String value;
}

这可以正确地解析JSON:

"Parameter":{
"Name":"Parameter-Name",
"Value":"Parameter-Value"
}

如果没有注释,推断的属性名称(从JSON匹配)将是“set”,而不是“isSet”,这似乎是意图。这是因为根据Java Beans规范,形式为“isXxx”和“setXxx”的方法表示有一个逻辑属性“xxx”需要管理。

我认为OldCurmudgeon和StaxMan都是正确的,但这里有一个简单的例子回答你。

@JsonProperty(name),告诉Jackson ObjectMapper将JSON属性名映射到带注释的Java字段名。

//example of json that is submitted
"Car":{
"Type":"Ferrari",
}


//where it gets mapped
public static class Car {
@JsonProperty("Type")
public String type;
}

不管怎样,现在……除了通常的序列化和反序列化之外,JsonProperty还用于为变量指定getter和setter方法。例如,假设你有一个这样的有效载荷:

{
"check": true
}

和一个反序列化类:

public class Check {


@JsonProperty("check")    // It is needed else Jackson will look got getCheck method and will fail
private Boolean check;


public Boolean isCheck() {
return check;
}
}

在本例中,需要JsonProperty注释。但是,如果在类中也有一个方法

public class Check {


//@JsonProperty("check")    Not needed anymore
private Boolean check;


public Boolean getCheck() {
return check;
}
}

看看这个文档: http://fasterxml.github.io/jackson-annotations/javadoc/2.13/com/fasterxml/jackson/annotation/JsonProperty.html < / p >

如您所知,这都是关于序列化和淡化对象的。假设有一个对象:

public class Parameter {
public String _name;
public String _value;
}

该对象的序列化是:

{
"_name": "...",
"_value": "..."
}

变量名直接用于序列化数据。如果你打算从系统实现中删除系统api,在某些情况下,你必须在序列化/反序列化中重命名变量。@JsonProperty是一个元数据,告诉序列化器如何序列化对象。它被用于:

  • 变量名
  • 存取(读,写)
  • 默认值
  • 必需的/可选

从示例:

public class Parameter {
@JsonProperty(
value="Name",
required=true,
defaultValue="No name",
access= Access.READ_WRITE)
public String _name;
@JsonProperty(
value="Value",
required=true,
defaultValue="Empty",
access= Access.READ_WRITE)
public String _value;
}

从JsonProperty javadoc,

定义逻辑属性的名称,即用于该属性的JSON对象字段名。如果value为空String(这是默认值),将尝试使用带注释的字段的名称。

除了其他答案,如果你在没有无参数构造函数的类中使用@JsonCreator注释,那么@JsonProperty注释就非常重要。

public class ClassToSerialize {


public enum MyEnum {
FIRST,SECOND,THIRD
}


public String stringValue = "ABCD";
public MyEnum myEnum;




@JsonCreator
public ClassToSerialize(MyEnum myEnum) {
this.myEnum = myEnum;
}


public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();


ClassToSerialize classToSerialize = new ClassToSerialize(MyEnum.FIRST);
String jsonString = mapper.writeValueAsString(classToSerialize);
System.out.println(jsonString);
ClassToSerialize deserialized = mapper.readValue(jsonString, ClassToSerialize.class);
System.out.println("StringValue: " + deserialized.stringValue);
System.out.println("MyEnum: " + deserialized.myEnum);
}
}

在这个例子中,唯一的构造函数被标记为@JsonCreator,因此Jackson将使用这个构造函数来创建实例。但是输出是这样的:

序列化:{“stringValue”:“ABCD”、“myEnum”:“第一”}

< p >异常 线程“主要” invalidformatexception:不能 构造的实例 ClassToSerialize MyEnum美元 from String value 'stringValue':不是已声明Enum的值 实例名:[FIRST, SECOND, THIRD]

但是在构造函数中添加@JsonProperty注释之后:

@JsonCreator
public ClassToSerialize(@JsonProperty("myEnum") MyEnum myEnum) {
this.myEnum = myEnum;
}

反序列化成功:

序列化:{“myEnum”:“第一”、“stringValue”:“ABCD”}

StringValue: ABCD

MyEnum:第一

添加JsonProperty还可以确保安全性,以防有人决定要更改其中一个属性名称,而没有意识到所讨论的类将被序列化为Json对象。如果他们改变了属性名,JsonProperty确保它将被用于Json对象,而不是属性名。

除了上面所有的答案之外,不要忘记文档中说

标记注释,用于将非静态方法定义为 "setter"或"getter"用于逻辑属性(取决于其 签名),或使用的非静态对象字段(序列化的,

.

.

如果你的类中有一个non-static方法,它不是常规的getter or setter方法,那么你可以通过对它使用注释来使它像getter and setter一样工作。参见下面的示例

public class Testing {
private Integer id;
private String username;


public Integer getId() {
return id;
}


public void setId(Integer id) {
this.id = id;
}


public String getUsername() {
return username;
}


public void setUsername(String username) {
this.username = username;
}


public String getIdAndUsername() {
return id + "." + username;
}


public String concatenateIdAndUsername() {
return id + "." + username;
}
}

当上述对象被序列化时,则响应将包含

  • 来自getUsername()的用户名
  • id来自getId()
  • idAndUsername from getIdAndUsername*

由于方法getIdAndUsernameget开始,因此它被视为普通的getter,因此,为什么你可以用@JsonIgnore注释它。

如果你注意到concatenateIdAndUsername没有返回,这是因为它的名称不是以get开头,如果你希望该方法的结果包含在响应中,那么你可以使用@JsonProperty("..."),它将被视为正常的getter/setter,如上面突出显示的文档中所述。