2012-05-25 11 views
7

Tenemos un conjunto de clases de dominio que se serializan a json a través de jackson usando servicios de jersey. Actualmente estamos anotando las clases con JAXB (aunque no estamos atados a eso). Esto funciona bien Pero queremos ofrecer diferentes serializaciones de las clases para diferentes casos de uso.Un modelo de dominio, múltiples vistas json

  • sitio Web
  • aplicaciones móviles
  • herramienta de administración
  • API pública

En cada uno de estos casos hay diferentes campos, que podemos o no desea incluir en la vista JSON . Por ejemplo, la herramienta de administración puede necesitar algunos parámetros para establecer permisos en los datos. El cliente móvil necesita una URL diferente a una transmisión multimedia que el sitio web. El sitio web tiene convenciones de nombres particulares que necesita para los campos.

¿Cuál es la mejor práctica para gestionar diferentes asignaciones de json para diferentes puntos finales de servicio en Jersey?

Gracias!

+0

¿Cuál es su solución final para este propósito? Es un tema muy interesante, pero por qué sin ninguna respuesta o respuesta. Estoy lidiando con el mismo problema. Creo que Jacson JsonView es una buena elección. Puedes consultar la introducción. http://wiki.fasterxml.com/JacksonJsonViews – Dylan

+1

Terminamos haciendo pequeños HashSets para cada combinación de clase/vista que contenía las propiedades incluidas en la lista blanca que queríamos usar en json y luego pasamos el objeto a ObjectMapper con SimpleBeanPropertyFilter.filterOutAllExcept para crear el json –

+0

Rick. Gracias por tu ayuda. Es muy útil. – Dylan

Respuesta

4

Nota: Soy el EclipseLink JAXB (MOXy) de plomo y un miembro del grupo de expertos JAXB (JSR-222).

MOXy ofrece un enlace JSON basado en anotaciones JAXB, así como un documento de enlace externo que le permite aplicar asignaciones alternativas a un modelo de dominio. Voy a demostrar a continuación con un ejemplo.

metadatos como JAXB Anotaciones

A continuación se muestra un sencillo modelo de asignación de Java con las anotaciones JAXB estándar.

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 Metadatos # 1 (alternate1.xml)

Aquí vamos a utilizar el documento de mapeo XML para desasignar un par de campos, haciéndolos @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> 

metadatos alternativo # 2 (alternate2.xml)

Aquí vamos a trazar el modelo de Java a una estructura JSON diferente utilizando la extensión basado en la cartografía de ruta 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> 

Código demostración

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

} 

salida

a continuación es el resultado de la ejecución del código de demostración. Nota del mismo modelo de objetos Se produjeron 3 documentos JSON diferentes.

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

Para más información (de mi blog)

+0

Eso es genial, pero, ¿funciona específicamente con Jersey? –

+0

@RickMangi - Funcionará con cualquier implementación de JAX-RS. Los equipos de Jersey y MOXy trabajan en estrecha colaboración: https://github.com/jersey/jersey/tree/master/examples/json-moxy –

Cuestiones relacionadas