3

嗨,我有一个 Java 枚举,我想从 XML 来回序列化一个包含枚举值的变量以实现持久性。我的枚举是这样定义的......

public enum e_Type
{
    e_Unknown,
    e_Categoric,
    e_Numeric
}

我的变量是这样声明的......

private e_Type type;

我希望它进入这样的 XML 标记...

<type>value</type>

在 XML 中持久化枚举值的最佳实践是什么?

4

6 回答 6

8

查看 JAXB 注释,它们是 JDK 的一部分:

public static void main(String[] args) throws Exception {
    JAXBContext context = JAXBContext.newInstance(Foo.class);
    StringWriter sw = new StringWriter();
    context.createMarshaller().marshal(new Foo(), sw);
    System.out.println(sw);
}

@XmlRootElement
public static class Foo {
    @XmlElement
    private e_Type type = e_Type.e_Unknown;
}

@XmlEnum
public enum e_Type {
    e_Unknown,
    e_Categoric,
    e_Numeric
}

您可以进一步自定义输出,例如,如果您希望外部 XML 表示不同于内部 java 枚举项名称:

@XmlEnumValue("UNKNOWN")
e_Unknown

顺便说一句:对 java 类/枚举使用大写名称是一个非常严格的约定

于 2009-02-26T11:00:56.283 回答
7

在收到关于 3rd 方库的回复后,我决定自己修复它,并认为我会发布我的解决方案,以防其他人需要看到它。我刚刚在枚举中添加了两个静态方法,它们负责来回发送到 XML 的内容......

public enum e_Type
{
    e_Unknown,
    e_Categoric,
    e_Numeric;
    public static e_Type type(String token)
    {
        return e_Type.valueOf(token);
    }
    public static String token(e_Type t)
    {
        return t.name();
    }
}

这对我来说是一个好方法,因为这意味着我可以在序列化/反序列化期间使用 type() 和 token() 方法调用我的 getter 和 setter。我已将此扩展到我的所有枚举中。

我在使用 3rd 方库时遇到了两个主要问题:

  1. 膨胀。这对我的小坚果来说是个大锤
  2. 依赖。添加一个新的 3rd 方库意味着我必须通过许可和法律检查以及 ESCROW 等。对于 8 行代码来说真的不值得。
于 2009-02-26T10:26:54.900 回答
5

尝试使用 XStream,它是一个将对象从 xml 转换为 xml 的库,并且也支持枚举。

String xml = xstream.toXML(enumObject);

http://x-stream.github.io/converters.html

于 2009-02-26T09:08:29.097 回答
2

另一个框架是类似于 C# XML 序列化的简单 XML 序列化。它可以处理任何对象图,包括那些包含枚举的对象图。

Serializer serializer = new Persister();

persister.write(myObject, myOutput);

枚举的序列化使用最终的 name() 方法,因此它们总是可以从 XML 中恢复。

于 2009-02-26T09:25:01.147 回答
1

我喜欢第一种方法。对于这样一个简单的任务,不需要包含第三方库。但是,使序列化值 == 枚举常量字面量(即“e_Unknown”、“e_Categoric”、“e_Numeric”)意味着如果开发人员重命名变量名称,它会使存储的值不可读。例如,您将 e_Unknown 保存在 XML 中,稍后将常量重命名为 UNKNOWN(为了命名)。然后您将无法检索旧值。

另一种方法是为每个枚举分配一个业务值,并将业务值存储在数据库中,这样常量名称的重命名/重构就不会破坏旧的存储值。如果您需要更多说明,我已经在博客中讨论过这个问题:3 methods to serialize Java Enums

于 2010-01-20T21:28:52.307 回答
0

我会第二次投票给 JAXB 2,XStream 也不错。就其价值而言,Simple 看起来很像 XStream。另请注意,注释的使用是可选的——在大多数情况下,它可以找出自动使用的字段和/或方法。而且您根本不需要使用 XML 模式(如果您愿意,可以):许多网站声称您这样做,但这是错误的(即使是简单页面也声称类似这样)。

至于外部依赖关系:如果您在 JDK 1.6 上运行,它会附带 JAXB 的捆绑实现(不仅仅是 API!)。虽然 JDK 可以避免它的臃肿(因为不是每个人都需要它,所以那些需要它的人可以只是 d/l 它 IMO),如果您确实需要它,那就太好了。并且实现非常好,非常快(仅原始 XML 解析或写入速度的 50-70%)。

于 2009-02-26T20:05:09.313 回答