IT

@JsonProperty 속성은 언제 사용되며 어떤 용도로 사용됩니까?

lottoking 2020. 6. 11. 08:08
반응형

@JsonProperty 속성은 언제 사용되며 어떤 용도로 사용됩니까?


이 콩 'State':

public class State {

    private boolean isSet;

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

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

}

아약스 '성공'콜백을 사용하여 유선으로 전송됩니다.

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

여기에 @JsonProperty 주석이 필요합니까? 그것을 사용하면 어떤 이점이 있습니까? 부작용 없이이 주석을 제거 할 수 있다고 생각합니다.

https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations 에서이 주석에 대해 읽으면 언제 사용해야하는지 모르겠습니까?


좋은 예가 있습니다. JSON이 .Net속성이 대문자로 시작 하는 환경에서 나오기 때문에 변수 이름을 바꾸는 데 사용합니다 .

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

이것은 JSON과 올바르게 구문 분석합니다.

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

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
}

그리고 Deserializer 클래스 :

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


Without annotations, inferred property name (to match from JSON) would be "set", and not -- as seems to be the intent -- "isSet". This is because as per Java Beans specification, methods of form "isXxx" and "setXxx" are taken to mean that there is logical property "xxx" to manage.


As you know, this is all about serialize and desalinize an object. Suppose there is an object:

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

The serialization of this object is:

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

The name of variable is directly used to serialize data. If you are about to remove system api from system implementation, in some cases, you have to rename variable in serialization/deserialization. @JsonProperty is a meta data to tell serializer how to serial object. It is used to:

  • variable name
  • access (READ, WRITE)
  • default value
  • required/optional

from example:

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

Adding the JsonProperty also ensures safety in case someone decides they want to change one of the property names not realizing the class in question will be serialized to a Json object. If they change the property name the JsonProperty ensures it will be used in the Json object, and not the property name.


As addition to other answers, @JsonProperty annotation is really important if you use the @JsonCreator annotation in classes which do not have a no-arg constructor.

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

In this example the only constructor is marked as @JsonCreator, therefore Jackson will use this constructor to create the instance. But the output is like:

Serialized: {"stringValue":"ABCD","myEnum":"FIRST"}

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of ClassToSerialize$MyEnum from String value 'stringValue': value not one of declared Enum instance names: [FIRST, SECOND, THIRD]

But after the addition of the @JsonProperty annotation in the constructor:

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

The deserialization is successful:

Serialized: {"myEnum":"FIRST","stringValue":"ABCD"}

StringValue: ABCD

MyEnum: FIRST


In addition to all the answers above, don't forget the part of the documentation that says

Marker annotation that can be used to define a non-static method as a "setter" or "getter" for a logical property (depending on its signature), or non-static object field to be used (serialized, deserialized) as a logical property.

If you have a non-static method in your class that is not a conventional getter or setter then you can make it act like a getter and setter by using the annotation on it. See the example below

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

When the above object is serialized, then response will contain

  • username from getUsername()
  • id from getId()
  • idAndUsername from getIdAndUsername*

Since the method getIdAndUsername starts with get then it's treated as normal getter hence, why you could annotate such with @JsonIgnore.

If you have noticed the concatenateIdAndUsername is not returned and that's because it name does not start with get and if you wish the result of that method to be included in the response then you can use @JsonProperty("...") and it would be treated as normal getter/setter as mentioned in the above highlighted documentation.


From JsonProperty javadoc,

Defines name of the logical property, i.e. JSON object field name to use for the property. If value is empty String (which is the default), will try to use name of the field that is annotated.

참고URL : https://stackoverflow.com/questions/12583638/when-is-the-jsonproperty-property-used-and-what-is-it-used-for

반응형