@JsonProperty özelliği ne zaman kullanılır ve ne için kullanılır?


183

Bu fasulye 'Devlet':

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' geri çağrısı kullanılarak tel üzerinden gönderilir:

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

@JsonProperty ek açıklaması burada gerekli mi? Kullanmanın avantajı nedir? Sanırım bu ek açıklamayı herhangi bir yan etkiye neden olmadan kaldırabilirim.

Bu duyuru hakkında okuma https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations adresinde Bunun ne zaman kullanılması gerektiğini bilmiyorum?


Yanıtlar:


238

İşte iyi bir örnek. JSON .Netözellikleri büyük harfle başladığı bir ortamdan geliyor çünkü değişkeni yeniden adlandırmak için kullanın .

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

Bu, JSON'a doğru bir şekilde ayrıştırılır:

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

1
Dize üye değişkenleri doğru durumlarına göre yeniden adlandırılamaz, bu nedenle genel Dize adı; genel Dize Adı olur; ?
blue-sky

14
Evet, bunu yapabilirler, ancak Java ortamında kodlama standartlarına uymuyorlar. Daha ziyade gerçek bir kodlama meselesi hakkında bilgim hakkında, ancak @JsonPropertyek açıklamaların gerçek bir kullanımının iyi ama basit bir örneğidir .
OldCurmudgeon

Bu ek açıklama tür üyesi için kullanılabilir Doublemi? Sadece tip olması Stringya da JSON destek herhangi bir tür olup olmadığını merak ediyorum ? Herhangi bir tür olabilir mi? @OldCurmudgeon
Dreamer

3
@Dreamer Evet. Tür alakasız. Bu yalnızca adı etkiler .
OldCurmudgeon

1
@Pavan - Bunun adlandırma ile bir ilgisi olmayacak. Ben istiyorum sanırım size ayarlayıcıları incelemek gerekir.
OldCurmudgeon

44

Bence OldCurmudgeon ve StaxMan her ikisi de doğru ama sizin için basit bir örnekle bir cümle cevabı burada.

@JsonProperty (ad), Jackson ObjectMapper'a JSON özellik adını açıklamalı Java alanının adıyla eşlemesini söyler.

//example of json that is submitted 
"Car":{
  "Type":"Ferrari",
}

//where it gets mapped 
public static class Car {
  @JsonProperty("Type")
  public String type;
 }

Sınıf adı JSON'un kök öğesiyle aynı mı olmalıdır? Bu benim için çalışmıyor.
Pavan

39

iyi şimdi ne için değer ... JsonProperty ALSO her zamanki seri ve deserialization dışında değişken için alıcı ve ayarlayıcı yöntemleri belirtmek için kullanılır. Örneğin, bunun gibi bir yükünüz olduğunu varsayalım:

{
  "check": true
}

ve bir Deserializer sınıfı:

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

Sonra bu durumda JsonProperty ek açıklaması gerekir. Ancak sınıfta da bir yöntem varsa

public class Check {

  //@JsonProperty("check")    Not needed anymore
  private Boolean check;

  public Boolean getCheck() {
     return check;
  }
}

Bu belgelere de bir göz atın: http://fasterxml.github.io/jackson-annotations/javadoc/2.3.0/com/fasterxml/jackson/annotation/JsonProperty.html


15

Ek açıklamalar olmadan, çıkartılan mülk adı (JSON'dan eşleşecek şekilde) "ayar" olur ve amaç olarak göründüğü gibi "isSet" olmaz. Bunun nedeni, Java Beans spesifikasyonuna göre, "isXxx" ve "setXxx" form yöntemlerinin, yönetilecek mantıksal özellik "xxx" olduğu anlamına gelmesi içindir.


1
Bu, soruda verilen özel dava için doğru cevaptır
Andrew Spencer

6

Bildiğiniz gibi, bu tamamen bir nesneyi serileştirmek ve tuzdan arındırmakla ilgilidir. Bir nesne olduğunu varsayalım:

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

Bu nesnenin serileştirmesi:

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

Değişkenin adı doğrudan verileri serileştirmek için kullanılır. Sistem api'sini sistem uygulamasından kaldırmak üzereyseniz, bazı durumlarda serileştirme / serileştirmedeki değişkeni yeniden adlandırmanız gerekir. @JsonProperty, serileştiriciye seri nesneye nasıl yapılacağını bildiren bir meta veridir. Aşağıdakiler için kullanılır:

  • değişken ismi
  • erişim (OKU, YAZ)
  • varsayılan değer
  • Gerekli / isteğe bağlı

örneğin:

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'nin eklenmesi, birisinin söz konusu sınıfın fark etmediği özellik adlarından birini değiştirmek istediğine karar vermesi durumunda güvenliği de sağlar. Özellik adını değiştirirlerse JsonProperty, özellik adı yerine Json nesnesinde kullanılmasını sağlar.


3

Diğer cevaplara ek olarak, @JsonPropertyek açıklamayı @JsonCreatorarg-no yapıcısı olmayan sınıflarda kullanırsanız ek açıklama gerçekten önemlidir .

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

Bu örnekte tek kurucu olarak işaretlenmiştir @JsonCreator, bu nedenle Jackson örneği oluşturmak için bu kurucuyu kullanacaktır. Ama çıktı şöyle:

Serileştirilmiş: {"stringValue": "ABCD", "myEnum": "FIRST"}

"Main" iş parçacığındaki istisna com.fasterxml.jackson.databind.exc.InvalidFormatException: 'stringValue' String değerinden ClassToSerialize $ MyEnum örneği oluşturulamıyor : değer Enum örneği adlarından biri değil: [FIRST, SECOND, THIRD]

Ancak, @JsonPropertyyapıcıya ek açıklama eklendikten sonra :

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

Serileştirme başarılı:

Serileştirilmiş: {"myEnum": "FIRST", "stringValue": "ABCD"}

StringValue: ABCD

MyEnum: İLK


2

Yukarıdaki tüm cevaplara ek olarak, belgelerin şu kısmını da unutmayın:

Statik olmayan bir yöntemi bir mantıksal özellik (imzasına bağlı olarak) veya mantıksal olarak kullanılacak statik olmayan nesne alanı (serileştirilmiş, serileştirilmiş) için "ayarlayıcı" veya "alıcı" olarak tanımlamak için kullanılabilen işaretçi notu Emlak.

non-staticSınıfınızda konvansiyonel olmayan bir yönteminiz getter or settervarsa, getter and setterüzerindeki açıklamayı kullanarak a gibi davranmasını sağlayabilirsiniz . Aşağıdaki örneğe bakın

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

Yukarıdaki nesne serileştirildiğinde, yanıt aşağıdakileri içerecektir:

  • kullanıcı adı getUsername()
  • kimliği getId()
  • getIdAndUsername* adresinden idAndUsername

Yöntem ile getIdAndUsernamebaşladığından beri getnormal alıcı olarak kabul edilir, bu yüzden neden böyle açıklama ekleyebilirsiniz @JsonIgnore.

concatenateIdAndUsernameİade edilmediğini fark ettiyseniz ve bunun nedeni adın başlamaması getve bu yöntemin sonucunun yanıta dahil edilmesini istiyorsanız, bunu kullanabilirsiniz @JsonProperty("...")ve getter/setteryukarıda vurgulanan belgelerde belirtildiği gibi normal olarak ele alınacaktır. .


0

JsonProperty javadoc'tan,

Mantıksal özelliğin adını, yani özellik için kullanılacak JSON nesnesi alan adını tanımlar. Değer boşsa Dize (varsayılan değerdir), açıklamalı alanın adını kullanmaya çalışır.

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.