什么时候使用@JsonProperty属性,它的作用是什么?


181

这个bean的“状态”:

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 : function(response) {  
            if(response.State.isSet){   
                alert('success called successfully)
            }

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

https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations上阅读有关此注释的信息我不知道何时需要使用此注释?


Answers:


236

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

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

这可以正确地从JSON解析:

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

1
不能将String成员变量重命名为正确的大小写吗,所以不能使用公共String名称;成为公共字符串名称;?
蓝天

14
是的,它们可以,但是在Java环境中,它们不符合编码标准。一个真正的编码问题更多地是关于我的学步匠,但这是一个真正使用@JsonProperty注释的很好而简单的例子。
OldCurmudgeon 2012年

可以将此注释用于type的成员Double吗?我只是想知道类型是否必须是StringJSON支持的类型?可以是任何类型吗?@OldCurmudgeon
梦想家

3
@梦想家是的。类型无关紧要。这只会影响名称
OldCurmudgeon

1
@Pavan-这与命名没有任何关系。我你应该检查你的二传手。
OldCurmudgeon

44

我认为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;
 }

Class名称是否应与JSON的根元素相同。这对我不起作用。
帕万

39

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.3.0/com/fasterxml/jackson/annotation/JsonProperty.html


15

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


1
对于问题中给出的具体情况,这是正确的答案
Andrew Spencer

6

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

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; 
}

6

添加JsonProperty还可以确保安全,以防万一有人决定要更改其中一个没有实现相关类的属性名称,而该属性名称将被序列化为Json对象。如果他们更改了属性名称,则JsonProperty会确保它将在Json对象中使用,而不是在属性名称中使用。


3

除了其他答案外,@JsonProperty如果您@JsonCreator在没有no-arg构造函数的类中使用注释,则注释确实非常重要。

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”:“ FIRST”}

线程“主”中的异常com.fasterxml.jackson.databind.exc.InvalidFormatException:无法从字符串值'stringValue'构造ClassToSerialize $ MyEnum实例 :值不是声明的Enum实例名称之一:[FIRST,SECOND,THIRD]

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

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

反序列化成功:

序列化:{“ myEnum”:“ FIRST”,“ stringValue”:“ ABCD”}

字符串值:ABCD

MyEnum:第一


2

除了上述所有答案外,请不要忘记文档中的部分内容

标记批注,可用于将非静态方法定义为逻辑属性的“设置者”或“获取器”(取决于其签名),或将用作逻辑的非静态对象字段(序列化,反序列化)属性。

如果您non-static的类中有一个非常规的方法,getter or setter则可以getter and setter通过在其上使用注释使它像a一样起作用。参见下面的例子

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()
  • 来自getIdAndUsername*的idAndUsername

由于该方法getIdAndUsername始于,因此get将其视为普通吸气剂,因此为什么要用注释@JsonIgnore

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


0

从JsonProperty javadoc,

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.