2013-08-14 32 views
12

Spring ile birlikte JSON (de) serileştirme için Jackson kullanıyorum. Ancak, bazı durumlarda bir alanın iki katı olmakla ilgili bir sorun yaşıyorum.Jackson ile Yinelenen JSON Alanı

public class EpubBookmarkJsonModel extends AbstractBookmarkJsonModel { 
    private static final long serialVersionUID = 1L; 
    // Removed other fields for brevity 

    public EpubBookmarkJsonModel() { 
     this.mimeType = "application/epub+zip"; 
    } 
} 

sorun bu JSON serialize zaman, ben bir yinelenen mimeType alan elde ediyoruz:

özet uzatmak

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "mimeType") 
@JsonSubTypes({ 
    @JsonSubTypes.Type(value = ImageBookmarkJsonModel.class, name = "image/jpeg"), 
    @JsonSubTypes.Type(value = EpubBookmarkJsonModel.class, name = "application/epub+zip") 
}) 
public abstract class AbstractBookmarkJsonModel extends AbstractJsonModel { 
    protected String mimeType; 
    // Removed other fields for brevity 

    public String getMimeType() { 
     return mimeType; 
    } 

    public void setMimeType(String mimeType) { 
     this.mimeType = mimeType; 
    } 

    @Override 
    public String toString() { 
     ObjectMapper mapper = new ObjectMapper(); 

     try { 
      return mapper.writeValueAsString(this); 
     } catch (IOException e) { 
      throw new IllegalStateException("Cannot convert object of type " + this.getClass().toString() + " to JSON", e); 
     } 
    } 
} 

Ve somut bir sınıfı:

ben soyut bir sınıf var
{ 
    "mimeType": "application/epub+zip", 
    "mimeType": "application/epub+zip", 
    "userId": 24, 
    "acid": "ACID-000000000029087", 
    "added": "2013-08-14T12:02:17Z", 
    "epubBookmarkId": 34, 
    "cfi": "epubcfi(/6/4!/2/68)", 
    "context": "CONTEXT" 
} 

nolu öneriyi kullanmayı denedim ObjectMapper üzerinde aynı ayarını yapmanın yanı sıra, yalnızca sınıftaki alanların kullanılmasının gerektiğini belirtmek içinanswers ekini kullanın, ancak bu sorunu gidermez.

Ek Açıklama:

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, 
     setterVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.NONE, 
     isGetterVisibility = JsonAutoDetect.Visibility.NONE) 

ObjectMapper:

ObjectMapper mapper = new ObjectMapper(); 
    mapper.getSerializationConfig().getDefaultVisibilityChecker() 
      .withFieldVisibility(JsonAutoDetect.Visibility.ANY) 
      .withGetterVisibility(JsonAutoDetect.Visibility.NONE) 
      .withSetterVisibility(JsonAutoDetect.Visibility.NONE) 
      .withCreatorVisibility(JsonAutoDetect.Visibility.NONE); 
+0

, ancak ek açıklamayı '@JsonTypeInfo (kullanım = JsonTypeInfo.Id.NAME kaldırırsanız, = şunlardır:

projedir açık kaynak, burayı kontrol JsonTypeInfo.As.PROPERTY, property = "mimeType") 'dan' abstractBookmarkJsonModel'den json – Katona

cevap

5

Bu davranış sınıfına AbstractBookmarkJsonModel üzerine yerleştirilen ek açıklamalardan kaynaklanır:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "mimeType") 
@JsonSubTypes({ 
    @JsonSubTypes.Type(value = ImageBookmarkJsonModel.class, name = "image/jpeg"), 
    @JsonSubTypes.Type(value = EpubBookmarkJsonModel.class, name = "application/epub+zip") 
}) 

@JsonTypeInfo mantıksal tip adını seri hale getirmek için Jackson söyler (JsonTypeInfo.Id.NAME) profesyonel olarak mimeType (property = "mimeType") adıyla perty (JsonTypeInfo.As.PROPERTY). @JsonSubTypes.Type ile application/epub+zip mantıksal adını EpubBookmarkJsonModel'a atarsınız. bu seri gelince

, Jackson özelliği mimeType = "application/epub+zip" mantıksal adı serializes daha sonra bunların arasında nesnenin özellikleri (yapıcıda atanmış) mantıksal adı application/epub+zip ile aynı değere sahip olur mimeType.

Jackson tipi bilgisi serileştirme aracılığıyla o ilgilenir beri mimeType mimeType alanı kaldırmak için @JsonTypeInfo ek açıklamada objectType değiştirildi veya daha iyi olması gerektiğini düşünüyorum.

+1

+ 1 'inizde sadece bir tane' mimeType 'var, bu doğru cevap, Jackson serileştirilmiş JSON çıkışına ek bir özellik ekler. alt türü tanımlayın. Sizin durumunuzda var olan bir özelliği kullanmaya çalışın, bunu yapmamalısınız. 'MimeType' özelliğini sınıftan kaldıramayacağınızı biliyorum çünkü ihtiyacınız olduğunu düşünüyorum. "SubtypeName" gibi başka bir alt tip bilgi özelliği kullanın ve alt tür adları "' ImageBookmark' "ve" 'EpubBookmark'" gibi bir şey kullanır. Bu, Jacksons Polymorphic Type Handling'in amaçlanan kullanımıdır. –

6

Yinelenen çıktıyla aynı sorunu yaşıyordum. Başka bir özelliği içermeyen bir çözüm buldum ve orijinal özelliğini kaldırmama izin verdi. İlk olarak, görünür bayrağı JsonTypeInfo için true olarak ayarladım. Sonra, mülk beyannamesi ve alıcıya bir JsonIgnore ek açıklaması ekledim (ancak setter değil). Bu, JSON'un tür özelliği için yalnızca bir anahtarla doğru şekilde çıktısını alıyor.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "mimeType") 
@JsonSubTypes({ 
    @JsonSubTypes.Type(value = ImageBookmarkJsonModel.class, name = "image/jpeg"), 
    @JsonSubTypes.Type(value = EpubBookmarkJsonModel.class, name = "application/epub+zip") 
}) 
public abstract class AbstractBookmarkJsonModel extends AbstractJsonModel { 
    @JsonIgnore 
    @JsonProperty("mimeType") 
    protected String mimeType; 

    @JsonIgnore 
    @JsonProperty("mimeType") 
    public String getMimeType() { 
     return mimeType; 
    } 

    @JsonProperty("mimeType") 
    public void setMimeType(String mimeType) { 
     this.mimeType = mimeType; 
    } 

} 

not etmek, bu şimdiye @JsonTypeInfo ek açıklamada JsonTypeInfo.As.EXISTING_PROPERTY kullanarak çözdü fasterxml jackson jackson-DataBind 2.1.1

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-databind</artifactId> 
    <version>2.1.1</version> 
</dependency> 
15

beraberdir.o yararlı olur olmadığını bilmiyorum ANS.java

+1

@JsonTypeInfo üzerinde görünür = true ile iyi bir çözüm (eğer yoksa, seri hale getirildikten sonra özellik sıfır) –

+0

Bu benim görüşüme göre kabul edilmiş bir cevap olmalı. Jackson'ın en temiz kullanımı. –

+0

"toJson()" üzerinde çalıştı ama "denJson()" denediğimde alan "null" değeriyle bırakıldı. Düşüncesi olan var mı? – ozma