2013-01-08 18 views
10

Mam klasę próbkowania:EclipseLink Moxy JSON serializacji

class Zoo { 
    public Collection<? extends Animal> animals; 
} 

Kiedy w odcinkach z Moxy, otrzymuję:

{ 
    "bird": [ 
     { 
      "name": "bird-1", 
      "wingSpan": "6 feets", 
      "preferredFood": "food-1" 
     } 
    ], 
    "cat": [ 
     { 
      "name": "cat-1", 
      "favoriteToy": "toy-1" 
     } 
    ], 
    "dog": [ 
     { 
      "name": "dog-1", 
      "breed": "bread-1", 
      "leashColor": "black" 
     } 
    ] 
} 

Dlaczego jest za pomocą wskaźników tablicy "[]", podczas gdy ptak , kot i pies nie są tablicami? Po drugie, czy istnieje sposób na pozbycie się "ptaka", "kota" i "psa"?

Innymi słowy, staram się dostać do:

{ 
     { 
      "name": "bird-1", 
      "wingSpan": "6 feets", 
      "preferredFood": "food-1" 
     } 
    , 
     { 
      "name": "cat-1", 
      "favoriteToy": "toy-1" 
     } 
    , 
     { 
      "name": "dog-1", 
      "breed": "bread-1", 
      "leashColor": "black" 
     } 
} 

Dzięki, Behzad

Odpowiedz

9

Pytanie # 1

Dlaczego jest za pomocą wskaźników tablicy „[] ", podczas gdy ptak, kot i pies są nie tablicami?

Aby uzyskać tę reprezentację JSON został odwzorowany model z @XmlElementRef adnotacji który opowiada JAXB używać wartość adnotacji @XmlRootElement jak wskaźnik spadków. Z wiązaniem JSON MOXy stają się kluczami. Tworzymy wartość tych kluczy tablic JSON, ponieważ klucze nie mogą się powtarzać.

Zoo

W modelu masz @XmlElementRef adnotacji na swoim animals pola/nieruchomość.

import java.util.Collection; 
import javax.xml.bind.annotation.XmlElementRef; 

class Zoo { 
    @XmlElementRef 
    public Collection<? extends Animal> animals; 
} 

Animal

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Bird.class, Cat.class, Dog.class}) 
public abstract class Animal { 

    private String name; 

} 

Ptak

Na każdej z podklas masz @XmlRootElement adnotacji.

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Bird extends Animal { 

    private String wingSpan; 
    private String preferredFood; 

} 

input.json/Output

{ 
    "bird" : [ { 
     "name" : "bird-1", 
     "wingSpan" : "6 feets", 
     "preferredFood" : "food-1" 
    } ], 
    "cat" : [ { 
     "name" : "cat-1", 
     "favoriteToy" : "toy-1" 
    } ], 
    "dog" : [ { 
     "name" : "dog-1", 
     "breed" : "bread-1", 
     "leashColor" : "black" 
    } ] 
} 

Aby uzyskać więcej informacji


pytanie # 2

drugie, czy istnieje sposób, aby pozbyć się "ptak", "kot" i "pies"?

Będziesz potrzebował jakiegoś wskaźnika dziedziczenia do reprezentowania różnych podklas.

OPCJA # 1 - @XmlDescriminatorNode/@XmlDescriminatorValue

Tutaj zrobić to za pomocą Moxy za @XmlDescriminatorNode/@XmlDescriminatorValue adnotacje.

Zoo

import java.util.Collection; 

class Zoo { 
    public Collection<? extends Animal> animals; 
} 

Animal

import javax.xml.bind.annotation.*; 
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Bird.class, Cat.class, Dog.class}) 
@XmlDiscriminatorNode("@type") 
public abstract class Animal { 

    private String name; 

} 

Ptak

import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; 

@XmlDiscriminatorValue("bird") 
public class Bird extends Animal { 

    private String wingSpan; 
    private String preferredFood; 

} 

input.json/Output

{ 
    "animals" : [ { 
     "type" : "bird", 
     "name" : "bird-1", 
     "wingSpan" : "6 feets", 
     "preferredFood" : "food-1" 
    }, { 
     "type" : "cat", 
     "name" : "cat-1", 
     "favoriteToy" : "toy-1" 
    }, { 
     "type" : "dog", 
     "name" : "dog-1", 
     "breed" : "bread-1", 
     "leashColor" : "black" 
    } ] 
} 

Aby uzyskać więcej informacji

OPCJA # 2 - @XmlClassExtractor

ClassExtractor (Animal Extractor)

Możesz napisać kod, który określi odpowiednią podklasę na podstawie zawartości JSON.

import org.eclipse.persistence.descriptors.ClassExtractor; 
import org.eclipse.persistence.sessions.*; 

public class AnimalExtractor extends ClassExtractor { 

    @Override 
    public Class extractClassFromRow(Record record, Session session) { 
     if(null != record.get("@wingSpan") || null != record.get("@preferredFood")) { 
      return Bird.class; 
     } else if(null != record.get("@favoriteToy")) { 
      return Cat.class; 
     } else { 
      return Dog.class; 
     } 
    } 

} 

Animal

@XmlClassExtractor adnotacja jest używana do określenia ClassExtractor.

import javax.xml.bind.annotation.*; 
import org.eclipse.persistence.oxm.annotations.XmlClassExtractor; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Bird.class, Cat.class, Dog.class}) 
@XmlClassExtractor(AnimalExtractor.class) 
public abstract class Animal { 

    private String name; 

} 

Ptak

Ze względu na to, jak Moxy przetwarza @XmlElement i @XmlAttribute adnotacje, którekolwiek z danych, które chcesz zostać udostępnione ClassExtractor będą musiały być opatrzone @XmlAttribute. Wejście

import javax.xml.bind.annotation.XmlAttribute; 

public class Bird extends Animal { 

    @XmlAttribute 
    private String wingSpan; 

    @XmlAttribute 
    private String preferredFood; 

} 

.json/Output

{ 
    "animals" : [ { 
     "wingSpan" : "6 feets", 
     "preferredFood" : "food-1", 
     "name" : "bird-1" 
    }, { 
     "favoriteToy" : "toy-1", 
     "name" : "cat-1" 
    }, { 
     "breed" : "bread-1", 
     "leashColor" : "black", 
     "name" : "dog-1" 
    } ] 
} 

Aby uzyskać więcej informacji


CODE DEMO

Poniższy kod demonstracyjny może być użyty z obydwoma mapowaniami opisanymi powyżej.

import java.util.*; 
import javax.xml.bind.*; 
import javax.xml.transform.stream.StreamSource; 
import org.eclipse.persistence.jaxb.JAXBContextProperties; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     Map<String, Object> properties = new HashMap<String, Object>(); 
     properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json"); 
     properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false); 
     JAXBContext jc = JAXBContext.newInstance(new Class[] {Zoo.class}, properties); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     StreamSource json = new StreamSource("src/forum14210676/input.json"); 
     Zoo zoo = unmarshaller.unmarshal(json, Zoo.class).getValue(); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(zoo, System.out); 
    } 

} 
+1

Dziękuję bardzo za odpowiedź. –

+0

Dziękuję bardzo za odpowiedź. Dostaję wyjątek podczas deklinalizacji. Nie mogę zaktualizować wpisu. Dodałem tę informację jako odpowiedź. Dzięki za pomoc! –

+0

@BehzadPirvali - Czy możesz zgłosić problem, który widzisz jako nowe pytanie? –