【问题标题】:Simple XML deserialization简单的 XML 反序列化
【发布时间】:2010-12-27 00:15:47
【问题描述】:

我正在试用Simple XML serializer。我对从 XML-> Java 反序列化更感兴趣。这是我作为单元测试的代码:

import java.io.StringReader;
import java.io.StringWriter;

import junit.framework.TestCase;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

public class SimpleTest extends TestCase {
    public void testWriting() throws Exception {
        StringWriter writer = new StringWriter();
        Address address = new Address("1234 Main Street", "San Francisco", "CA");
        Serializer serializer = new Persister();

        serializer.write(address, writer);
        System.out.println("Wrote: " + writer.getBuffer());
    }

    public void testReading() throws Exception {
        String input = "<address street='1234 Main Street' city='San Francisco' state='CA'/>";
        Serializer serializer = new Persister();
        System.out.println("Read back: " + serializer.read(Address.class, new StringReader(input)));
    }
}

@Root
class Address {
    @Attribute(name="street")
    private final String street;

    @Attribute(name="city")
    private final String city;

    @Attribute(name="state")
    private final String state;

    public Address(@Attribute(name="street") String street, @Attribute(name="city") String city, @Attribute(name="state") String state) {
        super();
        this.street = street;
        this.city = city;
        this.state = state;
    }

    @Override
    public String toString() {
        return "Address [city=" + city + ", state=" + state + ", street=" + street + "]";
    }   
}

这可行,但是 Address 类中重复的 @Attribute 注释(在字段和构造函数参数处)看起来很难看。有没有办法:

  • 从字段名中简单算出属性名吗?
  • 有简单的忽略序列化,这样我就可以不用注释字段或构造函数参数了吗?

【问题讨论】:

  • 如果您正在寻找简单的 XML->Java 反序列化并且不依赖于特定的包,这里有一个替代方案:sourceforge.net/projects/practicalxml(请注意,我没有将此作为答案,因为您似乎很高兴,这不是对待试图帮助您的人的好方法)
  • @kdgregory 谢谢,我没有绑定到特定的包——我会检查一下practicexml。请不要过于个人化地投票 - 所提供的建议远不能解决我的问题,而且很吵,IMO。
  • @kdgregory 再三考虑,我太高兴了。向大家道歉。
  • 另一个非常好的库是 XStream。到目前为止,我已经能够用它做我需要的一切。 :-)

标签: java xml xml-serialization serialization


【解决方案1】:

我认为您不需要所有的重复和额外的注释属性。如果名称与对象属性相同,则默认使用。

所以你可以把它声明为:

@Root
class Address {
    @Attribute
    private final String street;

    @Attribute
    private final String city;

    @Attribute
    private final String state;

    public Address(String street, String city, String state) {
        super();
        this.street = street;
        this.city = city;
       this.state = state;
   }

   @Override
   public String toString() {
      return "Address [city=" + city + ", state=" + state + ", street=" + street + "]";
   }   
}

【讨论】:

  • 我的错,我没有仔细注意你想要一个不可变的地址。基于当前的简单,您需要有重复的@Attribute 标签,因为它使用属性上的注释进行序列化和构造函数进行反序列化。您可以在属性上没有名称标签但在构造函数参数上没有名称标签,因为编译器只按顺序而不是按名称跟踪它。
  • 取决于您要实现的目标。当然,您可以使类可变,并在 setter 中手动强制执行不变性。但是话又说回来,代码会变得丑陋。在两者之间,我可能会选择双注释选项。
  • @DJ 感谢您的澄清!我原以为构造函数参数注释需要 name 属性(因为编译器删除了参数名称),但是从字段中删除 name 属性会导致“注释不匹配”错误。
【解决方案2】:

如果类成员实现Serializable 并遵守 JavaBean 语法,Java 将默认序列化所有类成员。

【讨论】:

  • 我认为您误解了这个问题。我想要一个 XML->Java 反序列化器。
  • Java 序列化是双向的。如果您使用 Java 序列化将 Java 对象序列化为 XML,您还可以将它们从 XML 反序列化为 Java 对象。这个过程是透明和灵活的。在一个应用程序中,我使用 Java 的 XML 序列化/反序列化将对象树写入磁盘并根据用户的请求将它们读回——我们正在谈论数十万个文件——在我看来,它运行良好。查看 java.sys-con.com/node/37550 的示例 - 关键类是 XMLEncoderXMLDecoder
【解决方案3】:

我也有类似的担忧,但对象结构非常复杂。 我通过使用 JAXB 库进行编组和反编组解决了这个问题,这是一种非常常见的方法。 您还可以考虑通过使用方面将编组逻辑与您的 java 类完全分离 - 您可以在一个单独的方面处理所有注释,这将使您的 java 类完全从编组注释中清除。

【讨论】:

    猜你喜欢
    • 2020-07-10
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 2015-05-18
    • 2014-11-11
    相关资源
    最近更新 更多