将Java枚举序列化为XML的最佳做法是什么?

时间:2009-02-26 09:05:02

标签: java xml serialization enums persistence

您好我有一个Java枚举,我希望序列化一个包含来自XML的枚举值的变量以实现持久性。我的枚举定义如下......

public enum e_Type
{
    e_Unknown,
    e_Categoric,
    e_Numeric
}

我的变量声明如下......

private e_Type type;

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

<type>value</type>

在XML中保存枚举值的最佳做法是什么?

6 个答案:

答案 0 :(得分: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

btw:对java类/枚举

使用大写名称是一个非常强大的约定

答案 1 :(得分: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行代码来说真的不值得。

答案 2 :(得分:5)

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

String xml = xstream.toXML(enumObject);

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

答案 3 :(得分:2)

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

Serializer serializer = new Persister();

persister.write(myObject, myOutput);

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

我会第二次投票给JAXB 2,XStream也很好。简单的外观很像XStream的价值。另请注意,使用注释是可选的 - 在大多数情况下,它可以找出自动使用的字段和/或方法。而且你根本不需要使用XML模式(如果你愿意,你可以使用):很多网站声称你这么做,但这是错误的(即使是简单的页面声称有这样的东西)。

关于外部依赖:如果你在JDK 1.6上运行,它会附带JAXB的捆绑实现(不仅仅是API!)。虽然JDK可以做到这一点很臃肿(因为不是每个人都需要它,但那些人可能会把它当作IMO),如果你确实需要的话,这很好。并且实现非常好,非常快(仅仅是原始XML解析或写入速度的50-70%)。