2012-05-25 13 views
7

Abbiamo un set di classi di dominio che vengono serializzate in json tramite jackson utilizzando i servizi jersey. Stiamo attualmente annotando le classi con JAXB (anche se non siamo legati a questo). Funziona bene Ma vogliamo offrire diverse serializzazioni delle classi per diversi casi d'uso.Un modello di dominio, più viste JSON

  • sito Web
  • Applicazioni mobili
  • strumento di amministrazione
  • API pubblica

In ciascuno di questi casi ci sono diversi campi che si può o non si vuole inclusi nella vista JSON . Ad esempio, lo strumento di amministrazione potrebbe richiedere alcuni parametri per l'impostazione delle autorizzazioni sui dati. Il client mobile ha bisogno di un URL diverso per un flusso multimediale rispetto al sito web. Il sito web ha particolari convenzioni di denominazione di cui ha bisogno per i campi.

Qual è la procedura migliore per gestire diversi mapping di JSON per diversi endpoint di servizio in Jersey?

Grazie!

+0

Qual è la tua soluzione finale per lo scopo? È un argomento molto interessante, ma perché senza alcuna risposta o risposta. Sto affrontando lo stesso problema. Penso che Jacson JsonView sia una buona scelta. È possibile fare riferimento all'introduzione. http://wiki.fasterxml.com/JacksonJsonViews – Dylan

+1

Abbiamo finito per creare piccoli HashSet per ogni combinazione di classi/viste contenente le proprietà autorizzate che volevamo usare in json e poi abbiamo passato l'oggetto a e ObjectMapper con SimpleBeanPropertyFilter.filterOutAllExcept per creare il json –

+0

Rick. Grazie per l'aiuto. È molto utile – Dylan

risposta

4

Nota: Sono in vantaggio EclipseLink JAXB (MOXy) e un membro del gruppo di esperti JAXB (JSR-222).

MOXy offre l'associazione JSON basata su annotazioni JAXB e un documento di collegamento esterno che consente di applicare mapping alternativi a un modello di dominio. Dimostrerò di seguito con un esempio.

metadati come JAXB NOTE

Qui di seguito è una semplice mappatura modello di Java con le annotazioni standard di JAXB.

package forum10761762; 

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Customer { 

    int id; 

    @XmlElement(name="first-name") 
    String firstName; 

    @XmlElement(name="last-name") 
    String lastName; 

} 

alternativo Metadata # 1 (alternate1.xml)

Qui useremo il documento di mappaggio XML per eliminare la mappatura di un paio di campi rendendoli @XmlTransient.

<?xml version="1.0"?> 
<xml-bindings 
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" 
    package-name="forum10761762"> 
    <java-types> 
     <java-type name="Customer"> 
      <java-attributes> 
       <xml-transient java-attribute="id"/> 
       <xml-transient java-attribute="firstName"/> 
      </java-attributes> 
     </java-type> 
    </java-types> 
</xml-bindings> 

metadati alternativo # 2 (alternate2.xml)

Qui si mappare il modello di Java per una diversa struttura JSON utilizzando percorso basato estensione mappatura di moxy.

<?xml version="1.0"?> 
<xml-bindings 
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" 
    package-name="forum10761762"> 
    <java-types> 
     <java-type name="Customer"> 
      <java-attributes> 
       <xml-element java-attribute="firstName" xml-path="personalInfo/firstName/text()"/> 
       <xml-element java-attribute="lastName" xml-path="personalInfo/lastName/text()"/> 
      </java-attributes> 
     </java-type> 
    </java-types> 
</xml-bindings> 

Demo Codice

package forum10761762; 

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

public class Demo { 

    public static void main(String[] args) throws Exception { 
     Customer customer = new Customer(); 
     customer.id = 123; 
     customer.firstName = "Jane"; 
     customer.lastName = "Doe"; 

     Map<String, Object> properties = new HashMap<String, Object>(); 
     properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json"); 
     properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false); 

     // Output #1 
     JAXBContext jc1 = JAXBContext.newInstance(new Class[] {Customer.class}, properties); 
     marshal(jc1, customer); 

     // Output #2 
     properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum10761762/alternate1.xml"); 
     JAXBContext jc2 = JAXBContext.newInstance(new Class[] {Customer.class}, properties); 
     marshal (jc2, customer); 

     // Output #2 
     properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum10761762/alternate2.xml"); 
     JAXBContext jc3 = JAXBContext.newInstance(new Class[] {Customer.class}, properties); 
     marshal(jc3, customer); 
    } 

    private static void marshal(JAXBContext jc, Object object) throws Exception { 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(object, System.out); 
     System.out.println(); 
    } 

} 

uscita

Di seguito si riporta l'uscita dalla esecuzione del codice demo. Nota dallo stesso modello di oggetto sono stati prodotti 3 diversi documenti JSON.

{ 
    "id" : 123, 
    "first-name" : "Jane", 
    "last-name" : "Doe" 
} 
{ 
    "last-name" : "Doe" 
} 
{ 
    "id" : 123, 
    "personalInfo" : { 
     "firstName" : "Jane", 
     "lastName" : "Doe" 
    } 
} 

per ulteriori informazioni (dal mio blog)

+0

È grandioso, ma funziona specificamente con Jersey? –

+0

@RickMangi - Funzionerà con qualsiasi implementazione JAX-RS. I team di Jersey e MOXy lavorano a stretto contatto: https://github.com/jersey/jersey/tree/master/examples/json-moxy –

Problemi correlati