何时使用@JsonProperty属性以及它用于什么?

时间:2012-09-25 13:07:21

标签: java ajax jackson

这个豆'州':

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'callback:

通过线路发送
        success : function(response) {  
            if(response.State.isSet){   
                alert('success called successfully)
            }

这里需要注释@JsonProperty吗?使用它有什么好处? 我想我可以删除这个注释而不会产生任何副作用。

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

9 个答案:

答案 0 :(得分:184)

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

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

这正确解析JSON:

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

答案 1 :(得分:33)

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

答案 2 :(得分:30)

以及它现在的价值...... 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

答案 3 :(得分:11)

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

答案 4 :(得分:3)

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

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

此对象的序列化是:

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

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

  • 变量名称
  • 访问(READ,WRITE)
  • 默认值
  • 需要/可选的

来自示例:

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

答案 5 :(得分:3)

作为对其他答案的补充,如果在没有无参数构造函数的类中使用@JsonProperty注释,@JsonCreator注释非常重要。

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:不能   构造实例   ClassToSerialize $ MyEnum    from String value'stringValue':value不是声明的Enum之一   实例名称:[FIRST,SECOND,THIRD]

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

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

反序列化成功:

  

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

     

StringValue:ABCD

     

MyEnum:FIRST

答案 6 :(得分:3)

添加JsonProperty还可以确保安全,以防有人决定要更改其中一个属性名称而不会意识到有问题的类将序列化为Json对象。如果他们更改属性名称,JsonProperty将确保它将在Json对象中使用,而不是属性名称。

答案 7 :(得分:0)

来自JsonProperty javadoc,

  

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

答案 8 :(得分:0)

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

  

标记注释,可用于将非静态方法定义为   逻辑属性的“ 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()中的用户名
  • getId()的ID
  • 来自getIdAndUsername *的
  • idAndUsername

由于方法getIdAndUsernameget开头,因此将其视为普通吸气剂,为什么要用@JsonIgnore进行注释。

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