Конвертировать объект Java в XML - PullRequest
4 голосов
/ 11 мая 2011

Я пытаюсь преобразовать объект Java внутри библиотеки Java в файл XML.Тем не менее, я получил эту проблему:

A a = new A();

// initializing for a

JAXBContext jc = JAXBContext.newInstance("libraryA.A");

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(a, System.out);

Затем я получил это исключение:

javax.xml.bind.JAXBException: "libraryA.a" doesnt contain ObjectFactory.class or jaxb.index
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:186)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:290)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:244)

Если я изменю: JAXBContext jc = JAXBContext.newInstance("libraryA.a");

на:

JAXBContext jc = JAXBContext.newInstance(libraryA.A.class);

тогда у меня есть еще одно исключение:

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions

library.A is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at library.A

library.A does not have a no-arg default constructor.
    this problem is related 

to the following location:
    at library.A

Ответы [ 2 ]

14 голосов
/ 11 мая 2011

Справочная информация (от Связанный вопрос )

Из комментария, который вы сделали в ответ на мой предыдущий вопрос, модель домена уже используется с JAXB.Самый простой способ установить связь между вашим клиентом и сервером через XML - это использовать уже аннотированную модель на обоих концах.

Я только что проверил исходный код моего клиента.В этом процессе нам необходимо преобразовать обратно xml-файл, сгенерированный из объектов java, в xml-файл, используя: javax.xml.bind.JAXBContext & javax.xml.bind.Marshaller.так что мой вопрос можно ли прочитать обратно XML-файл в те же объекты Java?тогда мы можем использовать объекты Java для дальнейшего шага.Заранее спасибо!

ОБНОВЛЕНИЕ

Похоже, что ваша проблема связана с наличием модели предметной области, которая определяется через интерфейсы с поддерживающими классами реализации.Ниже я продемонстрирую, как вы можете справиться с этим с помощью реализации JAXB (Metro, MOXy, JaxMe и т. Д.).

Демонстрационный код

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(CustomerImpl.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Customer customer = (Customer) unmarshaller.unmarshal(xml);

        Address address = customer.getAddress();
        System.out.println(address.getStreet());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }

}

Модель интерфейса

Следующие интерфейсы представляют нашу модель домена.Эти интерфейсы нельзя использовать для начальной загрузки JAXBContext.

Customer

public interface Customer {

    public Address getAddress();

    public void setAddress(Address address);

}

Адрес

public interface Address {

    public String getStreet();

    public void setStreet(String street);

}

Классы реализации

Классы реализации - это то, что будет отображаться в XML с использованием JAXB.

CustomerImpl

Примечание. В классе CustomerImpl мы используем аннотацию @XmlElement в свойстве address, чтобы указать тип AddressImpl.

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

@XmlRootElement(name="customer")
public class CustomerImpl implements Customer {

    private Address address;

    @XmlElement(type=AddressImpl.class)
    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

}

AddressImpl

public class AddressImpl implements Address {

    private String street;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

}

input.xml

<?xml version="1.0" encoding="UTF-8"?>
<customer>
    <address>
        <street>1 Any Street</street>
    </address>
</customer>
1 голос
/ 11 мая 2011

Если вам не нужно использовать JAXB, возможно, вы можете использовать XStream ?

Это накладывает очень мало ограничений на то, что вы можете сериализовать в / из XML, и может быть целесообразным, если вам не нужен JAXB , в частности .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...