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


183

이 콩 '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 에서이 주석에 대해 읽으면 언제 사용해야하는지 모르겠습니까?


답변:


238

좋은 예가 있습니다. 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 멤버 변수의 이름을 올바른 대소 문자로 바꿀 수 없으므로 public String name; 공개 문자열 이름이됩니다. ?
blue-sky

14
그렇습니다.하지만 Java 환경에서는 코딩 표준과 일치하지 않습니다. 실제 코딩 문제는 내 pedantry에 관한 것이지만 @JsonProperty주석을 실제로 사용하는 좋은 예입니다 .
OldCurmudgeon

이 주석을 유형의 멤버에 사용할 수 있습니까 Double? String유형이 JSON인지 지원하는 유형인지 궁금합니다 . @OldCurmudgeon
Dreamer

3
@Dreamer 네. 유형은 관련이 없습니다. 이것은 이름 에만 영향을 미칩니다 .
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;
 }

클래스 이름은 JSON의 루트 요소와 같아야합니다. 이것은 나를 위해 작동하지 않습니다.
Pavan

39

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


15

주석이 없으면 유추 된 속성 이름 (JSON과 일치)이 의도 된 것처럼 "isSet"이 아닌 "set"이됩니다. Java Beans 스펙에 따라 "isXxx"및 "setXxx"형식의 메소드는 관리 할 논리적 특성 "xxx"가 있음을 의미하기 때문입니다.


1
이것은 질문에 주어진 특정 사건에 대한 정답입니다
Andrew Spencer

6

아시다시피, 이것은 객체를 직렬화하고 desalinize하는 것입니다. 객체가 있다고 가정하십시오.

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

이 객체의 직렬화는 다음과 같습니다.

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

변수 이름은 데이터를 직렬화하는 데 직접 사용됩니다. 시스템 구현에서 시스템 API를 제거하려는 경우 직렬화 / 직렬화에서 변수의 이름을 바꿔야하는 경우가 있습니다. @JsonProperty는 serializer에게 객체를 직렬화하는 방법을 알려주는 메타 데이터입니다. 다음과 같은 용도로 사용됩니다.

  • 변수 이름
  • 액세스 (읽기, 쓰기)
  • 기본값
  • 필수 / 선택

예에서 :

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주석 을 사용하는 경우 주석이 실제로 중요합니다 .

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

스레드 "main"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"}

StringValue : ABCD

MyEnum : 첫 번째


2

위의 모든 답변 외에도 설명서의 일부를 잊지 마십시오.

비 정적 메소드를 논리 특성 (서명에 따라 다름)의 "세터"또는 "게터"로 정의하거나 논리로 사용 (직렬화, 역 직렬화) 할 비 정적 오브젝트 필드로 정의하는 데 사용할 수있는 마커 주석 특성.

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*

이 방법 getIdAndUsername은로 시작 get하므로 일반적인 getter로 취급되므로 왜 주석을 달 수 있습니까 @JsonIgnore?

당신이 발견 한 경우는 concatenateIdAndUsername반환의이 이름이로 시작하지 않기 때문되지 get당신이 응답에 포함되는 메소드의 결과를 원하는 경우 다음 사용할 수 @JsonProperty("...")있으며이 정상적으로 처리 될 수 getter/setter위의 강조 문서에서 언급 한 바와 같이 .


0

JsonProperty javadoc에서

논리적 속성의 이름, 즉 속성에 사용할 JSON 객체 필드 이름을 정의합니다. 값이 빈 문자열 인 경우 (기본값) 주석이 달린 필드의 이름을 사용하려고합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.