2010-05-13 11 views
12

Parece que la última JAX-RS puede manejar métodos que devuelven java.util.List como XMLRootElement pero no JAXB normal. Me gustaría imitar lo que CXF y Jersey están haciendo.Cómo clasifico java.util.List con JAXB como JAX-RS (CXF y Jersey) do

En otras palabras, me gustaría Marcar una lista y al igual que CXF y Jersey. Normalmente, si intenta reunir una lista con JAXB obtiene la excepción de Elemento raíz. ¿Cómo puedo evitar esto sin tener que hacer un objeto de embalaje?

EDIT: Gracias por las muchas respuestas, pero estoy muy familiarizado con @XmlElementWrapper pero eso ni siquiera se acerca a simular lo que JAX-RS está haciendo.

JAX-RS hace esto:

@XmlRootElement(name="dog") 
public class Dog { 
    private String name; 
    public String getName() { return this.name; } 
    //Setter also 
} 

Ahora bien, si me serializar una lista de perros:

serialize(List<Dog> dogs); 

XML debe ser (lo que JAX-RS hace):

<dogs> 
    <dog><name>Rascal</name></dog> 
</dogs> 

Para que pueda ver, no quiero tener que crear un objeto contenedor para cada objeto de dominio.

+1

I Creo que esta podría ser la respuesta https://jaxb.dev.java.net/guide/Different_ways_of_ma rshalling.html # Marshalling_a_non_element –

+0

Parece que podría utilizar el código en: org.apache.cxf.jaxrs.provider.AbstractJAXBProvider –

+0

que quería decir JAXBElementProvider –

Respuesta

6

se puede no sólo tiene que añadir:

@XmlElementWrapper(name = "wrapperName") 

No hay necesidad de hacer un objeto envoltorio. Este será entonces el elemento de ruta en su respuesta XML agrupada.

+0

Sí, esta es la forma correcta de garantizar que las colecciones estén empaquetadas. Anota tu lista con @XmlElementWrapper según https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlElementWrapper.html –

2

Utilicé una lista iterativa personalizada con el siguiente código, espero que esto ayude.

package bindings; 

import java.io.Serializable; 
import java.util.Iterator; 
import java.util.LinkedList; 
import java.util.List; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlElementWrapper; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 

@XmlType 
@XmlRootElement 
public class CustomBindList<V> implements Iterable<V>, Serializable { 
     private static final long serialVersionUID = 4449835205581297830L; 

     @XmlElementWrapper(name = "List") 
     @XmlElement(name = "Entry") 
    private final List<V> list = new LinkedList<V>(); 

    public CustomBindList() { 
    } 

    public void add(final V obj) { 
      list.add(obj); 
    } 

    public V get(final int index) { 
     return list.get(index); 
    } 

    @Override 
    public Iterator<V> iterator() { 
     return list.iterator(); 
    } 

    public int size() { 
     return list.size(); 
    } 
} 
0

asignación de una lista puede ser hecho como éste ..

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType 
public class TestRootObject { 

    @XmlElement(name = "testList") 
    private List<TestObj> testList; 

    //getter setter 
} 
2

Tengo un secreto que me permite evitar atornillar con asignaciones de JAXB por completo y tener todo funciona mágicamente.

Han utilizado este enfoque durante años, nunca pasaron ni siquiera 5 minutos preocupándose por el marshalling/unmarshalling. El secreto es ... no uses JAXB. :)

En la mayoría de mis proyectos que usan JAX-RS, configuro Jersey para usar xstream y dejo que xstream averigüe cómo organizar/desenmascararme. (o jackson para JSON)

Quizás haya algunas razones para usar JAXB en lugar de algo como xstream/jackson, pero no he encontrado ninguna.

+0

Últimamente confío en Jackson JSON y olvido XML en total. –

0

check out de Jackson, es muy compatible con los enlaces de JAXB y al usar MappingJsonFactory puedes usar indistintamente Java to XML to Java to Json to Java.

0

Anoto mis colecciones con @XmlJavaTypeAdapter(value = Adapter.class). La clase de adaptador se extiende desde XmlAdapter<key, value> la clave es un identificador único para (des) marshal y el valor es su objeto de dominio.

Quizás esto te pueda ayudar. Sin embargo, debe crear un adaptador para cada objeto de dominio.

Cuestiones relacionadas