【问题标题】:Manually XML-serializing a Java object手动 XML 序列化 Java 对象
【发布时间】:2011-06-20 12:16:27
【问题描述】:

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

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

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

.class 文件显示了 XML 序列化属性,所以我想它们肯定是 XML 可序列化的。

如何对 Java 对象执行手动 XML 序列化?我可以在 C# 中做到这一点,但在 Java 中却不行。

谢谢

【问题讨论】:

  • 为什么要序列化这个对象?拨打 WS 电话还是有其他原因?在第一种情况下,您不需要手动序列化,否则使用一些序列化库,如 XStream。
  • 我需要存储对象以备后用;)
  • 更大的问题是,即使只需要将对象临时存储在 HttpSession 中,如果它不实现可序列化,许多 Web 容器也会立即崩溃。

标签: java xml-serialization


【解决方案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 ;
    }

【讨论】:

【解决方案2】:

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

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

我还将提供指向JiBXXMLBeansXStream 的强制性链接。它们都可以对 XML 进行编组和从 XML 解组。其中一些不需要像 Castor 那样的任何映射。

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

【讨论】:

    【解决方案3】:

    这是一种做事方式,另一种是让控制java客户端的人更合理一点。假设 Jax-ws 用于通过 wsimport 实用程序创建客户端,他们可以指定一个简单的小绑定文件,在 -b 选项中指定,如下所示:
    <?xml version="1.0" encoding="UTF-8"?>
    &lt;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"&gt;
    &lt;xs:annotation&gt;
    &lt;xs:appinfo&gt;
    &lt;jaxb:globalBindings&gt;
    &lt;xjc:serializable /&gt;
    &lt;/jaxb:globalBindings&gt;
    &lt;/xs:appinfo&gt;
    &lt;/xs:annotation&gt;
    &lt;/xs:schema&gt;

    它将自动将“可序列化”放在所有生成的类上。我还通过 jaxws-maven-plugin 在 Maven 中进行了这项工作。我相信其他客户端生成器也有类似的选项。

    HTH

    【讨论】:

    • 不幸的是,这是不可能的。但值得称赞的是,提到了“合理性”。我不知道他们使用什么工具,他们甚至可以使用自定义工具,因此也不可能手动实现 Serializable
    • 您是否有权访问 WSDL?可能是时候礼貌地生成您自己的客户了,如果有任何问题被问到,请微笑并回答:“它已被处理。” ;)
    • 没那么容易。我不允许修改 WSDL(尽管我已经能够非常规地阅读它),句号:)。不过,后端人员使用他们自己的工具
    • 我并不是说你会修改 WSDL,只是运行你自己的 wsimport 或 wsdl2java 来对付它。
    【解决方案4】:

    如果您的对象遵循 Java Beans 规范,并且您不在乎它们如何准确地表示为 XML,那么来自 Java 标准 API 的XMLEncoder 可以完成这项工作。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多