¿Cómo serializar y deserializar objetos usando JAXB?


Tengo un problema. Quiero convertir un objeto en otro usando JAXB. Como en, tengo una clase com.home.Student, y otra clase com.school.Student, ambos tienen los mismos argumentos, de hecho ambos son iguales (copiar y pegar), pero paquete diferente. Quiero realizar la conversión entre ellos usando JAXB.

Cómo hacer eso, por favor ayúdame.

 32
Author: KAD, 2011-03-04

3 answers

Puedes hacer lo siguiente.

Nota:

  • No requiere que usted materialice los datos como XML, aprovechando JAXBSource.
  • No requiere ninguna anotación en su modelo de objetos.

Com.casa.Estudiante

package com.home;

public class Student {

    private String name;
    private Status status;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

}

Com.casa.Situación

package com.home;

public enum Status {

    FULL_TIME("F"),
    PART_TIME("P");

    private final String code;

    Status(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

}

Com.escuela.Estudiante

package com.school;

public class Student {

    private String name;
    private Status status;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

}

Com.escuela.Situación

package com.school;

public enum Status {

    FULL_TIME("F"),
    PART_TIME("P");

    private final String code;

    Status(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

}

Com.ejemplo.Demo;

package com.example;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.util.JAXBSource;
import javax.xml.namespace.QName;

public class Demo {

    public static void main(String[] args) throws Exception {
        com.home.Student studentA = new com.home.Student();
        studentA.setName("Jane Doe");
        studentA.setStatus(com.home.Status.FULL_TIME);

        JAXBContext contextA = JAXBContext.newInstance(com.home.Student.class);
        JAXBElement<com.home.Student> jaxbElementA = new JAXBElement(new QName("student"), com.home.Student.class, studentA);
        JAXBSource sourceA = new JAXBSource(contextA, jaxbElementA);

        JAXBContext contextB = JAXBContext.newInstance(com.school.Student.class);
        Unmarshaller unmarshallerB = contextB.createUnmarshaller();
        JAXBElement<com.school.Student> jaxbElementB = unmarshallerB.unmarshal(sourceA, com.school.Student.class);

        com.school.Student studentB = jaxbElementB.getValue();
        System.out.println(studentB.getName());
        System.out.println(studentB.getStatus().getCode());
    }

}
 35
Author: Blaise Doughan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-09 14:28:42

Sería bueno que incluyeras algún código que explique tu problema.

JAXB 101 dice que debe colocar las anotaciones correctas, luego puede serializar y deserializar correctamente. Usted debe anotar correctamente sus clases con @XmlRootElement, @XmlElement, @XmlAttribute, etc

Por ejemplo:

@XmlRootElement(name="student")
@XmlAccessorType(XmlAccessType.NONE)
class Student {
  @XmlElement(name="name")
  private String name;

  @XmlElement(name="age")
  private int age;

  public Student() {
  }

  public String getName() { return name; }

  public int getAge() { return age; }
}

Entonces puedes usar serializarlo usando JAXB Marshaller :

StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(Student.class);
Marshaller m = context.createMarshaller();
m.marshal(student, writer);

Y deserializarlo también por Desmarcar la entrada ..

JAXBContext context = JAXBContext.newInstance(Student.class);
Unmarshaller m = context.createUnmarshaller();
return (Student)m.unmarshal(new StringReader(input));

Asegúrate de mirar el JavaDoc que mencioné anteriormente, ya que hay muchas maneras de hacerlo.

Si no puede modificar sus clases, todavía puede usar JAXB (o puede usar XStream) Asumiendo que su clase es la siguiente:

class Student {
  private String name;
  private int age;

  public Student() {
  }

  public void setName(String name) { this.name = name; }
  public String getName() { return name; }
  public void setAge(int age) { this.age = age; }
  public int getAge() { return age; }
}

Puedes serializarlo haciendo:

Student student = new Student();
student.setAge(25);
student.setName('FooBar');
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(Student.class);
Marshaller m = context.createMarshaller();
m.marshal(new JAXBElement(new QName(Student.class.getSimpleName()), Student.class, student), writer);
System.out.println(writer.toString());

Si está utilizando XStream, también puede hacer la serialización sin Anotaciones (y es más controlable). http://x-stream.github.io/tutorial.html

 32
Author: Mohamed Mansour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-12 08:45:09

Si su objetivo es simplemente convertir (asignar realmente) entre los dos, y son idénticos excepto el nombre del paquete, creo que podría usar reflexión simple. Simplemente itere sobre los campos del objeto de origen y asígnelos al campo del mismo nombre en el objeto de destino. Vagamente, así:

import java.lang.reflect.Field;

public class Converter {
    public void convert (com.home.Student src, com.school.Student dst) throws Exception {
        for (Field f : src.getFields()) {

            // src field name
            String name = f.getName();

            // get corresponding field in dst
            Field dstField = dst.getDeclaredField(name);

            dstField.set(dst, f.get());
        }
    }
}

Nota: No compilé esto, por lo que digo "vagamente". Tendrás que usar el campo.isAccessible () / Field.setAccessible (true) si los campos son privados, por lo que puede temporalmente cambia la accesibilidad mientras asignas valores. O bien, escribes código un poco más complejo que usa setters/getters públicos en lugar de usar directamente el acceso de campo.

 2
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-04 16:14:55