2012-05-25 2 views
7

Wir haben eine Reihe von Domain-Klassen, die nach json über jackson mit Hilfe von Jersey Services serialisiert werden. Wir notieren derzeit die Klassen mit JAXB (obwohl wir nicht daran gebunden sind). Das funktioniert gut. Wir möchten jedoch verschiedene Serialisierungen der Klassen für verschiedene Anwendungsfälle anbieten.Ein Domain-Modell, mehrere JSON-Ansichten

  • Website
  • Mobile Anwendungen
  • Admin-Tool
  • Öffentliche API

In jedem dieser Fälle gibt es verschiedene Felder, die wir in der json Ansicht nicht enthalten sein sollen oder nicht . Zum Beispiel benötigt das Admin-Tool möglicherweise einige Parameter zum Festlegen von Berechtigungen für Daten. Der mobile Client benötigt eine andere URL zu einem Medienstream als die Website. Die Website hat bestimmte Namenskonventionen für Felder.

Was ist die beste Vorgehensweise beim Verwalten verschiedener Zuordnungen von Json für verschiedene Dienstendpunkte in Jersey?

Danke!

+0

Was ist Ihre endgültige Lösung für den Zweck? Es ist ein sehr interessantes Thema, aber warum ohne Antwort oder Antwort. Ich habe das gleiche Problem. Ich denke Jacson JsonView ist eine gute Wahl. Sie können auf die Einleitung verweisen. http://wiki.fasterxml.com/JacksonJsonViews – Dylan

+1

Wir haben kleine HashSets für jede Klassen-/Ansichtskombination erstellt, die die Whitelist-Eigenschaften enthalten, die wir im json verwenden wollten, und dann das Objekt an ObjectMapper mit SimpleBeanPropertyFilter.filterOutAllExcept übergeben, um das zu erstellen JSON –

+0

Rick. Danke für Ihre Hilfe. Es ist sehr nützlich. – Dylan

Antwort

4

Hinweis: Ich bin das EclipseLink JAXB (MOXy) Blei und Mitglied der JAXB (JSR-222) Expertengruppe.

MOXy bietet eine JSON-Bindung basierend auf JAXB-Annotationen sowie ein externes Bindungsdokument, mit dem Sie alternative Zuordnungen auf ein Domänenmodell anwenden können. Ich werde unten mit einem Beispiel zeigen.

Metadaten als JAXB Anmerkungen

Unten finden Sie ein einfaches Java-Modell-Mapping mit den Standard-JAXB Annotationen ist.

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; 

} 

Alternate Metadata # 1 (alternate1.xml)

Hier werden wir das XML-Mapping-Dokument verwenden, um ein paar Felder unmap von ihnen @XmlTransient machen.

<?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> 

Alternate Metadata # 2 (alternate2.xml)

Hier werden wir das Java-Modell zu einem anderen JSON Struktur abzubilden moxy Pfad basierte Mapping-Erweiterung.

<?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-Code

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

} 

Ausgabe

Unten finden Sie die Ausgabe aus dem Demo-Code ausgeführt wird. Hinweis aus dem gleichen Objektmodell 3 verschiedene JSON-Dokumente wurden erstellt.

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

Weitere Informationen (aus meinem Blog)

+0

Das ist großartig, aber funktioniert es speziell mit Jersey? –

+0

@RickMangi - Es wird mit jeder JAX-RS-Implementierung arbeiten. Die Teams von Jersey und MOXy arbeiten eng zusammen: https://github.com/jersey/jersey/tree/master/examples/json-moxy –