Pregunta

Estamos utilizando Jersey (RESTO biblioteca de Java) para un proyecto durante los últimos meses y me encanta. Pero esta semana se han topado con un problema con JAXB.

Lo que tengo es un elemento que tiene 2 hijos, cada uno de ellos tiene niños donde algunos de sus hijos hacen referencia entre sí.

Te voy a enseñar algo de código.

Root root = new Root();

Parent parent1 = new Parent();
Parent parent2 = new Parent();

root.add(parent1);
root.add(parent2);

Child child1 = new Child();
Child child2 = new Child();
Child child3 = new Child();

parent1.add(child1);
parent1.add(child2);

parent2.add(child2);
parent2.add(child3);

Así que tenemos 1 raíz, 2 padres y 3 niños.

Si envío esto para arriba y abajo de la trayectoria JAXB, me parece que volver 4 hijos.
Cada padre tiene su propia copia de child2.

¿Hay alguna forma de conseguir JAXB a serialized relación y muestran que tanto Parent1 y el punto parent2 al mismo objeto?

Sólo encontramos este problema hace poco, cuando se están transmitiendo elementos más complejos.

Si no hay manera de conseguir JAXB para hacer esto (eso es lo que creo que por el momento), ¿alguien tiene alguna sugerencia de una manera que pudiera hacer algo de magia en Jersey a restablecer la relación?

¿Fue útil?

Solución

Esto no es un problema con JAXB tanto, ya que es un problema con el modelo. ¿Cómo le gustaría JAXB para rendir sus relaciones en XML, XML cuando se proporciona ningún mecanismo estándar para expresar esto? Consumidores y productores del XML tendrían que tener una capa de lógica de negocio que ponerse de acuerdo sobre el respresentation.

Le sugiero que necesita para remodelar sus datos. Por ejemplo, en lugar de tener a los niños como están contenidos en el interior de los padres, se puede aplanar las cosas:

<parent id="parent1">
   <child ref="child1"/>
   <child ref="child2"/>
</parent>

<parent id="parent2">
   <child ref="child2"/>
   <child ref="child3"/>
</parent>

<child id="child1"/>
<child id="child2"/>
<child id="child3"/>

Independientemente del mecanismo que lee y escribe esta estructura tendrá que saber qué significa todo esto, pero no veo ninguna otra buena manera de hacer esto.

Otro punto de interés es que xstream sí tiene apoyo a referencias a objetos cuando serializa / deserializa objeto gráficos, pero es un mecanismo completamente propietario.

Otros consejos

JAXB hace apoyar referencias no contención entre objetos en el árbol utilizando una combinación de @ XmlID / @ XmlIDREF. Un requisito para esto es que todos los objetos en el árbol también debe hacer referencia a una relación de contención. En su modelo de esto podría implicar dando Raíz una colección de niño.

A continuación sería una versión modificada de su código:

Root root = new Root(); 

Parent parent1 = new Parent(); 
Parent parent2 = new Parent(); 

root.add(parent1); 
root.add(parent2); 

Child child1 = new Child(); 
child1.id = "1";
root.add(child1);
parent1.add(child1); 

Child child2 = new Child();
child2.id = "2";
root.add(child2);
parent1.add(child2); 
parent2.add(child2); 

Child child3 = new Child();
child3.id = "3";
root.add(child3);
parent2.add(child3);

A continuación, las clases del modelo se vería así:

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Root {

    public List<Parent> parent = new ArrayList<Parent>();
    public List<Child> child = new ArrayList<Child>();

    public void add(Parent parent1) {
        parent.add(parent1);
    }

    public void add(Child child1) {
        child.add(child1);
    }
}

import javax.xml.bind.annotation.XmlIDREF;

public class Parent {

    @XmlIDREF
    public List<Child> child = new ArrayList<Child>();

    public void add(Child child1) {
        child.add(child1);
    }

}

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlID;

public class Child {

    @XmlID
    @XmlAttribute
    public String id;

}

El XML resultante se vería así:

<root>
    <parent>
        <child>1</child>
        <child>2</child>
    </parent>
    <parent>
        <child>2</child>
        <child>3</child>
    </parent>
    <child id="1"/>
    <child id="2"/>
    <child id="3"/>
</root>

usted podría hacerlo escribiendo una clase adaptador para la clase raíz, que en unmarshalling puede limpiar el menor se opone a eliminar los duplicados.

Es sólo una idea rápida:? Hacen los objetos Child implementar un método adecuado equals()

Como ya se ha dicho en otras respuestas. Este es el diseño de JAXB.

Lo que podría hacer es pegar manualmente las múltiples copias de lo que usted cree era el mismo objeto antes de serialización. A continuación, usted no necesitaría su propio distintivo de identificación para objetos, por lo que se podía diferenciar clones a partir de tan solo otros objetos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top