2013-01-08 24 views
10

Ho una classe di esempio:EclipseLink moxy serializzazione JSON

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

Quando serializzato con Moxy, sto ottenendo:

{ 
    "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" 
     } 
    ] 
} 

Perché è attraverso indicatori di array "[]", mentre uccello , gatto e cane non sono matrici? Secondo, c'è un modo per sbarazzarsi di "uccello", "gatto" e "cane"?

In altre parole, io sto cercando di ottenere a:

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

Grazie, Behzad

risposta

9

DOMANDA # 1

Perché è attraverso indicatori di array "[] ", mentre uccello, gatto e cane sono non matrici?

Per ottenere questa rappresentazione JSON aver mappato il modello con la @XmlElementRef annotazioni che racconta JAXB di utilizzare il valore della @XmlRootElement annotazioni come indicatore eredità. Con il binding JSON di MOXy questi diventano chiavi. Creiamo il valore di questi tasti array JSON poiché le chiavi non possono ripetere.

Zoo

nel modello si ha la @XmlElementRef annotazioni sul vostro animals campo/proprietà.

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; 

} 

Uccello

Su ciascuna delle vostre sottoclassi voi hanno un @XmlRootElement annotazione.

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" 
    } ] 
} 

Per ulteriori informazioni


Domanda # 2

In secondo luogo, c'è un modo per sbarazzarsi di "uccello", "gatto", e "cane"?

Avrai bisogno di una sorta di indicatore di ereditarietà per rappresentare le varie sottoclassi.

OPZIONE # 1 - @XmlDescriminatorNode/@XmlDescriminatorValue

Qui faccio @XmlDescriminatorNode/@XmlDescriminatorValue annotazioni questo usando del moxy.

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; 

} 

Uccello

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" 
    } ] 
} 

Per ulteriori informazioni

OPZIONE # 2 - @XmlClassExtractor

ClassExtractor (AnimalExtractor)

È possibile scrivere un codice che determinerà la sottoclasse appropriata in base al contenuto 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

Il @XmlClassExtractor annotazione viene utilizzato per specificare il 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; 

} 

Uccello

causa come Moxy elabora i @XmlElement e @XmlAttribute annotazioni, uno dei dati che si desidera mettere a disposizione per la ClassExtractor dovrà essere annotato con @XmlAttribute.

import javax.xml.bind.annotation.XmlAttribute; 

public class Bird extends Animal { 

    @XmlAttribute 
    private String wingSpan; 

    @XmlAttribute 
    private String preferredFood; 

} 

input .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" 
    } ] 
} 

Per ulteriori informazioni


CODICE DEMO

Il seguente codice demo può essere utilizzato con entrambi i mapping descritti sopra.

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

Grazie mille per la tua risposta. –

+0

Grazie mille per la tua risposta. Sto ottenendo un'eccezione durante la de-serializzazione. Non sono stato in grado di aggiornare il post. Ho aggiunto queste informazioni come risposta. Grazie per l'aiuto! –

+0

@BehzadPirvali - Potresti postare il problema che stai vedendo come una nuova domanda? –

Problemi correlati