手动XML序列化Java对象

时间:2011-06-20 12:16:27

标签: java xml-serialization

我目前必须存储一个实现Serializable的类的Java对象,但肯定是SOAP序列化的,因为它是从WSDL生成的, Web服务的输入。

事实上,标准Java序列化会抛出异常。我无法控制类,并且创建类的人不愿意手动标记它们Serializable,因为代理是从WSDL自动生成的(wsdl2java?他们没有告诉我...)。

所以我需要通过不可能在每个字段上循环来将该对象转换为其他对象。

.class文件显示了XML序列化属性,因此我认为它们绝对是XML可序列化的。

如何执行Java对象的手动XML序列化?我可以在C#中实现,但不能在Java中实现。

谢谢

4 个答案:

答案 0 :(得分:1)

你可以做到

 private byte[] encode(YourObject obj)
    {
        byte[] bytes = null;
        try
        {
            YourObject vsNew = new YourObject(obj)
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                GZIPOutputStream out = new GZIPOutputStream(baos);
                XMLEncoder encoder = new XMLEncoder(out);
                encoder.writeObject(vsNew);
                encoder.close();
                bytes = baos.toByteArray();
        }
        catch (Exception e)
        {
            _log.error("Exception caught while encoding/zipping ", e);
        }
        return bytes;
    }


    /*
     * Decode the report definition blob back to the
     * ScheduledReport object.
     */
    private YourObject decode(byte[] bytes)
    {
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        YourObject vSNew = null;
        try
        {
            GZIPInputStream in = new GZIPInputStream(bais);
            XMLDecoder decoder = new XMLDecoder(in);
            vSNew = (YourObject)decoder.readObject();
            decoder.close();
        }
        catch (Exception e)
        {
            _log.error("IOException caught while decoding/unzipping ", e);
        }
        return vSNew ;
    }

答案 1 :(得分:1)

如果您愿意(或其他人愿意)使用JAXB注释来努力注释类,那么JAXB将是从XML序列化和反序列化的直接选择。如果已经完成(您的问题表明XML序列化属性在类文件中可用),那么您需要使用JAXBContext和相关的API类(Marshaller和Unmarshaller)来编组和解组对象。

如果你付出了所有努力,你可以考虑Castor。我应该警告你,如果你没有映射,那么你可能对输出不满意。但是,如果您可以将依赖项导入项目 * ,这是序列化为XML的最快捷,最简单的方法。

我还会提供指向JiBXXMLBeansXStream的强制性链接。所有这些都可以执行XML编组和解组。其中一些不需要像Castor那样的任何映射。

* 过去曾尝试编写XML序列化程序,我建议不要编写自己的代码,试图完成Castor或类似的marshaller / unmarshaller所做的工作。在没有映射文件的情况下,它会涉及大量的反射。

答案 2 :(得分:1)

这是一种做事方式,另一种方式是......控制java客户端的人更合理一些。假设使用Jax-ws通过wsimport实用程序创建客户端,他们可以指定一个简单的小绑定文件,在-b选项中指定,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
elementFormDefault="qualified" attributeFormDefault="unqualified"
jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.1">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<xjc:serializable />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
</xs:schema>

它会自动将“serializable”放在所有生成的类上。我也通过jaxws-maven-plugin在Maven中工作了。我确信其他客户端生成器也有类似的选项。

HTH

答案 3 :(得分:0)

如果您的对象遵循Java Beans规范,并且您不关心它们如何被表示为XML,那么Java标准API中的XMLEncoder可以完成这项工作。

如果您的对象不是“纯粹的”JavaBeans,或者您需要对生成的XML进行更多控制,XStream是一个流行的XML序列化库。