2015-11-20 10 views
9

Gibt es eine Möglichkeit, uns für eine Klasse ohne @ XmlRootElement-Annotation zu entfernen? Oder sind wir verpflichtet, die Annotation einzugeben?JAXB-Unmarshalling ohne XmlRootElement-Annotation?

zum Beispiel:

public class Customer { 

    private String name; 
    private int age; 
    private int id; 

    public String getName() { 
     return name; 
    } 

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

    public int getAge() { 
     return age; 
    } 

    @XmlElement 
    public void setAge(int age) { 
     this.age = age; 
    } 

    public int getId() { 
     return id; 
    } 

    @XmlAttribute 
    public void setId(int id) { 
     this.id = id; 
    } 

} 

und lassen Sie den unmarshalling Code für richtig kommentierte Klasse wie:

try { 

     File file = new File("C:\\file.xml"); 
     JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class); 

     Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
     Customer customer = (Customer) jaxbUnmarshaller.unmarshal(file); 
     System.out.println(customer); 

     } catch (JAXBException e) { 
     e.printStackTrace(); 
     } 

die Details auszulassen.

Antwort

18

folgenden Code wird marshall verwendet und unmarshall withot @XmlRootElement

public static void main(String[] args) { 

     try { 

      StringWriter stringWriter = new StringWriter(); 

      Customer c = new Customer(); 
      c.setAge(1); 
      c.setName("name"); 

      JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class); 

      Marshaller marshaller = jaxbContext.createMarshaller(); 
      marshaller.marshal(new JAXBElement<Customer>(new QName("", "Customer"), Customer.class, null, c), stringWriter); 

      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
      InputStream is = new ByteArrayInputStream(stringWriter.toString().getBytes()); 
      JAXBElement<Customer> customer = (JAXBElement<Customer>) jaxbUnmarshaller.unmarshal(new StreamSource(is),Customer.class); 

      c = customer.getValue(); 

      } catch (JAXBException e) { 
      e.printStackTrace(); 
      } 

} 

obige Code funktioniert nur, wenn Sie @XmlAccessorType(XmlAccessType.PROPERTY) auf Customer-Klasse hinzufügen oder privat machen alle Attribute.

+0

in alternativen Versuch 'private' alle Attribute zu machen, sonst mit oder ohne' XmlRootElement', wird JAXB funktioniert nicht – Xstian

+1

auf die oben beschriebenen Sie erhalten keine andere Anmerkungen benötigen, außer ' @ XmlAttribute' und '@ XmlElement', aber sie beschreiben die Ausgabe – Xstian

+0

Ist es notwendig, vor dem Zurückmarshallen zu marshallieren? –

1

Wenn Sie XmlRootElement nicht zur vorhandenen Bean hinzufügen können, können Sie auch eine Halterklasse erstellen und diese mit Annotation als XmlRootElement markieren. Beispiel unten: -

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class CustomerHolder 
{ 
    private Customer cusotmer; 

    public Customer getCusotmer() { 
     return cusotmer; 
} 

    public void setCusotmer(Customer cusotmer) { 
     this.cusotmer = cusotmer; 
    } 
}