Java枚举类型序列化为XML的最佳实践是什么?

3

你好,我有一个Java枚举类型,想要将包含枚举值的变量序列化为XML以进行持久化。我的枚举类型定义如下...

public enum e_Type
{
    e_Unknown,
    e_Categoric,
    e_Numeric
}

我的变量声明如下...

private e_Type type;

我希望它可以放进一个像这样的XML标签中...
<type>value</type>

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

8
请查看JDK的一部分——JAXB注释。
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类/枚举中使用大写名称是非常强烈的传统。

7

在收到关于第三方库的反馈后,我决定自己修复它,并想着将我的解决方案发布出来,以便其他人需要时可以查看。我只是向枚举中添加了两个静态方法,处理发送和接收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。 我已将此扩展到所有我的枚举中。

我使用第三方库有两个主要问题:

  1. 臃肿。 对于我的小问题来说,这太过“大材小用”了
  2. 依赖性。 添加新的第三方库意味着我必须进行许可和法律检查以及ESCROW等。 对于8行代码真的不值得。

赞成 - 对于一个狭义定义的问题,提供简单易行的解决方案! - Kevin Day

5

2

另一个框架是Simple XML Serialization,类似于C#的XML序列化。它可以处理包括枚举在内的任何对象图。

Serializer serializer = new Persister();

persister.write(myObject, myOutput);

枚举的序列化使用了final name()方法,这样它们就可以始终从XML中恢复。

似乎一个非常简单的任务需要很多基础设施。我惊讶地发现没有本地方式。我会在谷歌上搜索你在这里提到的final name()的东西。 - Simon
是的,使用Enum.name()很简单,可以通过Enum.valueOf(Class, String)将其提取回来。只需传入枚举类和Enum.name()的值即可。这样就可以从文本格式中恢复枚举了 :) - ng.

1

我喜欢第一种方法。对于这样一个简单的任务,没有必要包含第三方库。然而,将序列化值==枚举常量文字(即“e_Unknown”,“e_Categoric”,“e_Numeric”)意味着如果开发人员重命名变量名称,则会使存储的值无法读取。例如,您在XML中保存e_Unknown,稍后将常量重命名为UNKNOWN(出于命名规范的考虑)。然后,您将无法检索旧值。

另一种方法是为每个枚举分配业务值,并将业务值存储在数据库中,以便常量名称的重命名/重构不会破坏旧的存储值。如果需要更多澄清,我已经在博客中写了关于这个问题:3 ways to serialize Java Enums


0

我会推荐使用JAXB 2,XStream也不错。Simple看起来很像XStream,不过这并没有多大价值。另外请注意,使用注释是可选的——在大多数情况下,它可以自动找出要使用的字段和/或方法。而且你根本不需要使用XML模式(如果你想使用可以):许多网站声称你需要使用XML模式,但这是错误的(即使Simple页面也声称了类似的事情)。

至于外部依赖项:如果你运行在JDK 1.6上,它附带了JAXB的捆绑实现(不仅是API!)。虽然这是JDK可以省略的杂质(因为并非每个人都需要它,那些需要它的人可以下载它IMO),但如果你确实需要它,它还是很好用的。实现非常好,速度非常快(只比纯粹的XML解析或写入慢50-70%)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接