将 Java 对象转换为 XML

发布于 2024-11-06 03:24:24 字数 1793 浏览 0 评论 0原文

我正在尝试将 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

I am trying to convert a Java object inside of a Java library to an XML file. However, I got this problem:

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);

Then I got this exception:

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)

If I change: JAXBContext jc = JAXBContext.newInstance("libraryA.a");

to:

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

then I have another exception:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

傲影 2024-11-13 03:24:24

背景信息(来自相关问题< /a>)

根据您对我对上一个问题的回答所做的评论,域模型已在 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。

客户

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 类中,我们在 address 上使用 @XmlElement 注释属性指定类型为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>

Background Info (From Related Question)

From the comment you made on my answer to your previous question the domain model is already being used with JAXB. The easiest way to have your client and server communicate via XML is to leverage the already annotated model on both ends.

I just have checked the source code of
my client. In the process, we need to
convert back a xml file which is
generated from java objects to xml
file using: javax.xml.bind.JAXBContext
& javax.xml.bind.Marshaller. so my
question is it possible to read back
the xml file to the same java objects?
then we can use the java objects for a
further step. Thanks in advance!


UPDATE

It appears as though your issue is due to having a domain model that is defined through interfaces with backing implementation classes. Below I'll demonstrate how you can handle this using a JAXB implementation (Metro, MOXy, JaxMe, etc).

Demo Code

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);
    }

}

Interface Model

The following interfaces represent our domain model. These interfaces when not be leveraged to bootstrap the JAXBContext.

Customer

public interface Customer {

    public Address getAddress();

    public void setAddress(Address address);

}

Address

public interface Address {

    public String getStreet();

    public void setStreet(String street);

}

Implementation Classes

The implementation classes are what will be mapped to XML using JAXB.

CustomerImpl

Note in the CustomerImpl class we use the @XmlElement annotation on the address property to specify the type is 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>
浅笑依然 2024-11-13 03:24:24

如果您不必使用 JAXB,也许您可​​以使用 XStream

它对您可以序列化到 XML 或从 XML 序列化的内容施加了很少的限制,并且如果您不需要专门使用 JAXB,那么它可能是合适的。

If you don't have to use JAXB, perhaps you can use XStream ?

It imposes very few restrictions on what you can serialise to/from XML, and may be appropriate if you don't need JAXB specifically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文