Neden bir oluşturucu @JsonCreator ile açıklandığında, argümanlarının @JsonProperty ile açıklanması gerekir?


109

Jackson'da, bir kurucuya ile açıklama eklediğinizde @JsonCreator, argümanlarına ile açıklama eklemeniz gerekir @JsonProperty. Yani bu kurucu

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

şuna dönüşür:

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

Neden gerekli olduğunu anlamıyorum. Açıklayabilir misin?

Yanıtlar:


113

Jackson, alanları bir JSON nesnesinden yapıcıya hangi sırayla geçireceğini bilmek zorundadır. Java'da yansıma kullanarak parametre adlarına erişmek mümkün değildir - bu nedenle bu bilgileri açıklamalarda tekrarlamanız gerekir.


9
Bu Java8 için geçerli değil
MariuszS

12
@MariuszS Bu doğru ama bu yazı Java8 derleyici bayrağı ve bir Jackson modülü yardımıyla gereksiz açıklamalardan nasıl kurtulacağınızı açıklıyor. Yaklaşımı test ettim ve işe yarıyor.
kuantum

Tabii ki, bir cazibe gibi çalışır :) docs.oracle.com/javase/tutorial/reflect/member/…
MariuszS

52

Parametre adlarına normalde çalışma zamanında Java kodu tarafından erişilemez (çünkü derleyici tarafından bırakılır), bu nedenle bu işlevselliği istiyorsanız ya Java 8'in yerleşik işlevlerini kullanmanız ya da erişim elde etmek için ParaNamer gibi bir kitaplık kullanmanız gerekir. ona.

Bu nedenle, Jackson'ı kullanırken yapıcı argümanları için ek açıklamalar kullanmak zorunda kalmamak için, bu 2 Jackson modülünden birini kullanabilirsiniz:

jackson-module-parametre-adları

Bu modül, Java 8 kullanırken açıklama içermeyen yapıcı argümanları almanızı sağlar . Kullanmak için önce modülü kaydetmeniz gerekir:

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

Ardından kodunuzu -parameters bayrağını kullanarak derleyin:

javac -parameters ...

Bağlantı: https://github.com/FasterXML/jackson-modules-java8/tree/master/parameter-names

Jackson modülü paranamer

Diğeri, sadece modülü kaydetmenizi veya bir açıklama iç gözlemi yapılandırmanızı gerektirir (ancak her ikisi de yorumlarda belirtildiği gibi değil). 1.8'den önceki Java sürümlerinde açıklamasız yapıcı argümanları kullanmanıza izin verir .

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

Bağlantı: https://github.com/FasterXML/jackson-modules-base/tree/master/paranamer


28

İsteğe bağlı olarak derleyicinin, yapıcı parametrelerinin adlarıyla birlikte meta verileri sunacağı jdk8 ile yapıcı açıklamalarını önlemek mümkündür. Daha sonra Jackson-module-parameter-names modülü ile Jackson bu kurucuyu kullanabilir. Jackson yazısında ek açıklamalar olmadan bir örnek görebilirsiniz


kullanımdan kaldırıldı ve jackson-modules-java8 / parameter-names
naXa


6

Basitçe java.bean.ConstructorProperties ek açıklaması kullanılabilir - çok daha az ayrıntılıdır ve Jackson da bunu kabul eder. Örneğin :

  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

Ben anladığınız zaman bu doğru, bir parametreli biriyle varsayılan kurucuyu yerini ve dolayısıyla onunla kurucusunu çağırmak için kullanılan JSON anahtarlarını tanımlamak gerekir.


3

İçinde precised olarak açıklama belgeleri , açıklama bağımsız değişken adı herhangi bir değişiklik yapmadan özellik adı kullanılan olduğunu gösterir, ancak farklı adı belirtmek için boş olmayan bir değere belirtilebilir:


0

Sadece onunla karşılaş ve bir yerde bir cevap al. 2.7.0'dan beri aşağıdaki ek açıklamayı kullanabilirsiniz

@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;
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.