2012-05-25 12 views
7

Mamy zestaw klas domen, które są serializowane do json za pośrednictwem jacksona przy użyciu usług jersey. Obecnie opisujemy klasy za pomocą JAXB (chociaż nie jesteśmy do tego przywiązani). To działa dobrze. Ale chcemy zaoferować różne serializacje klas dla różnych przypadków użycia.Jeden model domeny, wiele widoków json

  • strona internetowa
  • aplikacje mobilne
  • narzędzie Administrator
  • API Publiczne

W każdym z tych przypadków są różne pola które może lub nie chce zawarte w widoku json . Na przykład narzędzie administratora może wymagać pewnych parametrów do ustawiania uprawnień do danych. Klient mobilny potrzebuje innego adresu URL do strumienia mediów niż do strony internetowej. Witryna ma określone konwencje nazewnictwa, których potrzebuje dla pól.

Jaki jest najlepszy sposób zarządzania różnymi mapowaniami json dla różnych punktów końcowych usługi w Jersey?

Dzięki!

+0

Jakie jest twoje ostateczne rozwiązanie do tego celu? To bardzo ciekawy temat, ale dlaczego bez żadnej odpowiedzi czy odpowiedzi. Mam do czynienia z tym samym problemem. Myślę, że Jacson JsonView to dobry wybór. Możesz zapoznać się ze wstępem. http://wiki.fasterxml.com/JacksonJsonViews – Dylan

+1

Zakończyliśmy tworzenie małych zestawów HashSets dla każdej kombinacji klasy/widoku zawierających właściwości na białej liście, które chcieliśmy zastosować w jsonie, a następnie przekazaliśmy obiekt do obiektu i ObjectMapper za pomocą SimpleBeanPropertyFilter.filterOutAllExcept w celu utworzenia json –

+0

Rick. Dzięki za pomoc. To jest bardzo użyteczne. – Dylan

Odpowiedz

4

Uwaga: Jestem EclipseLink JAXB (MOXy) ołowiu i członkiem grupy JAXB (JSR-222) ekspertów.

MOXy oferuje wiązanie JSON oparte na adnotacjach JAXB, a także zewnętrzny dokument wiążący, który umożliwia stosowanie alternatywnych odwzorowań do modelu domeny. Przedstawię poniżej przykład.

Metadane jako JAXB adnotacji

Poniżej znajduje się prosty model Java mapowanie ze standardowymi adnotacji 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; 

} 

Alternatywny Metadane # 1 (alternate1.xml)

Tutaj będziemy używać dokument odwzorowania XML odmapować parę pól, czyniąc je @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> 

Alternatywny Metadane # 2 (alternate2.xml)

Tutaj będziemy mapować modelu Java do innej struktury JSON przy użyciu Moxy za ścieżki oparty rozszerzenie odwzorowania.

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

} 

Wyjście

Poniżej jest wyjście z uruchomieniem kodu demo. Uwaga z tego samego modelu obiektowego 3 wyprodukowano różne dokumenty JSON.

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

więcej informacji (z mojego bloga)

+0

To świetnie, ale czy to działa szczególnie w przypadku Jersey? –

+0

@RickMangi - Będzie działać z każdą implementacją JAX-RS. Zespoły Jersey i MOXy ściśle ze sobą współpracują: https://github.com/jersey/jersey/tree/master/examples/json-moxy –

Powiązane problemy