생성자가 @JsonCreator로 주석을다는 경우 왜 그 인수는 @JsonProperty로 주석을 달아야합니까?


108

Jackson에서는 생성자에를 주석으로 추가 할 때 @JsonCreator인수에 @JsonProperty. 그래서이 생성자는

public Point(double x, double y) {
    this.x = x;
    this.y = y;
}

이렇게됩니다 :

@JsonCreator
public Point(@JsonProperty("x") double x, @JsonProperty("y") double y) {
    this.x = x;
    this.y = y;
}

왜 필요한지 모르겠습니다. 설명해 주시겠습니까?

답변:


112

Jackson은 JSON 객체에서 생성자로 필드를 전달하는 순서를 알아야합니다. 리플렉션을 사용하여 Java에서 매개 변수 이름에 액세스 할 수 없습니다. 이것이 주석에서이 정보를 반복해야하는 이유입니다.


9
이것은 Java8에 유효하지 않습니다
MariuszS

12
@MariuszS 사실이지만이 게시물 은 Java8 컴파일러 플래그와 Jackson 모듈의 도움으로 불필요한 주석을 제거하는 방법을 설명합니다. 나는 접근 방식을 테스트했으며 작동합니다.
quantum

물론 매력처럼 작동합니다. :) docs.oracle.com/javase/tutorial/reflect/member/…
MariuszS

52

매개 변수 이름은 일반적으로 런타임시 Java 코드에서 액세스 할 수 없습니다 (컴파일러에 의해 드롭되기 때문). 따라서 해당 기능을 원할 경우 Java 8의 내장 기능을 사용하거나 액세스를 얻기 위해 ParaNamer와 같은 라이브러리를 사용해야합니다. 그것에.

따라서 Jackson을 사용할 때 생성자 인수에 대한 주석을 사용할 필요가 없도록 다음 두 Jackson 모듈 중 하나를 사용할 수 있습니다.

잭슨 모듈 매개 변수 이름

이 모듈을 사용하면 Java 8을 사용할 때 주석이없는 생성자 인수를 얻을 수 있습니다 . 이를 사용하려면 먼저 모듈을 등록해야합니다.

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ParameterNamesModule());

그런 다음 -parameters 플래그를 사용하여 코드를 컴파일합니다.

javac -parameters ...

링크 : https://github.com/FasterXML/jackson-modules-java8/tree/master/parameter-names

잭슨 모듈 매개 변수

다른 하나는 단순히 모듈을 등록하거나 주석 내부 검사를 구성하기 만하면됩니다 (주석에서 지적한대로 둘다는 아닙니다). 1.8 이전의 Java 버전에서 주석이없는 생성자 인수를 사용할 수 있습니다 .

ObjectMapper mapper = new ObjectMapper();
// either via module
mapper.registerModule(new ParanamerModule());
// or by directly assigning annotation introspector (but not both!)
mapper.setAnnotationIntrospector(new ParanamerOnJacksonAnnotationIntrospector());

링크 : https://github.com/FasterXML/jackson-modules-base/tree/master/paranamer


28

선택적으로 컴파일러가 생성자 매개 변수의 이름으로 메타 데이터를 도입하는 jdk8로 생성자 주석을 피할 수 있습니다. 그런 다음 jackson-module-parameter-names 모듈로 Jackson은이 생성자를 사용할 수 있습니다. 주석없이 Post Jackson 에서 예제를 볼 수 있습니다.


로 사용되지 않으며 이동 잭슨 - 모듈 - java8 / 매개 변수 - 이름
naXa

6

Java 바이트 코드는 메소드 또는 생성자 인수의 이름을 유지하지 않기 때문입니다.



1
@MariuszS 실제로, 그러나 이것이 새로운 (그리고 기본이 아닌 컴파일러 플래그)이기 때문에 Jackson은 계속해서 @JsonProperty주석 을 지원해야 할 것입니다
lcfd

6

java.bean.ConstructorProperties 주석을 사용할 수 있습니다. 훨씬 덜 장황하고 Jackson도 허용합니다. 예 :

  import java.beans.ConstructorProperties;

  @ConstructorProperties({"answer","closed","language","interface","operation"})
  public DialogueOutput(String answer, boolean closed, String language, String anInterface, String operation) {
    this.answer = answer;
    this.closed = closed;
    this.language = language;
    this.anInterface = anInterface;
    this.operation = operation;
  }

4

이 사실을 올바르게 이해 하면 기본 생성자를 매개 변수화 된 생성자로 대체하므로 생성자를 호출하는 데 사용되는 JSON 키를 설명해야합니다.


3

어노테이션 문서 에서 정확하게 설명한대로 어노테이션은 인수 이름이 수정없이 속성 이름으로 사용됨을 나타내지 만 비어 있지 않은 값으로 지정하여 다른 이름을 지정할 수 있습니다.


0

그냥 와서 어딘가에 답을 얻었습니다. 2.7.0부터 아래 주석을 사용할 수 있습니다.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class Point {
    final private double x;
    final private double y;

    @ConstructorProperties({"x", "y"})
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.