【问题标题】:Simple 2.6.7 doesn't handle enums in the same way as Simple 2.6 does?Simple 2.6.7 不像 Simple 2.6 那样处理枚举?
【发布时间】:2026-01-23 02:20:08
【问题描述】:

考虑以下使用 simple-xml 注释的枚举:

@Root(name="days")
public enum DaysOfWeek {

    SUNDAY("blue", 30),
    MONDAY("green", 60),
    TUESDAY("yellow", 50),
    WEDNESDAY("red", 45),
    THURSDAY("black", 45),
    FRIDAY("white", 65),
    SATURDAY("brown", 40);

    @Attribute(name="color")
    private String color;

    @Element(name="mins")
    private int minutes;


    DaysOfWeek(String color, int minutes){
        this.color = color;
        this.minutes = minutes;
    }

    DaysOfWeek(){
        /*
         * Default constructor
         */
    }

    public void setColor(String color){
        this.color = color;
    }

    public void setMinutes(int minutes){
        this.minutes = minutes;
    }

    public String getColor(){
        return this.color;

    }

    public int getMinutes(){
        return this.minutes;
    }
}

并且,使用简单框架将其序列化为 XML 的代码:

    StringWriter writer = new StringWriter();
    try {
        serializer.write(DaysOfWeek.TUESDAY, writer);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println(writer.toString());

使用 simple-2.6,我看到了这个输出 - 这是我所期望的:

<days color="yellow">
   <mins>50</mins>
</days>

但是,相同的代码,当使用 simple-2.6.7 序列化时,会给出:

<daysOfWeek>TUESDAY</daysOfWeek>

基本上,在 simple-2.6.7 中,枚举的各个成员(及其上的 simple-xml 注释)被忽略,并且始终使用枚举常量的名称进行序列化。

这是故意的吗?如何在考虑枚举的各个成员的同时获取最新版本的 simple-xml 来序列化枚举?

【问题讨论】:

  • 我刚刚试用了最新版的 Simple XML (2.7.0)。问题似乎仍然存在。
  • 问题仍然存在于 2.7.1 中。

标签: java enums xml-serialization simple-framework


【解决方案1】:

在 (2.6.x) 版本的 changelog 中只有一个条目包含 enum

简单 2.6.3:
- 修复错误以确保抽象枚举可以正确序列化

但是为什么要对colorminutes 进行序列化呢?如果您序列化和反序列化DaysOfWeek,枚举将根据您的定义(构造函数)获取它们的值。


无论如何,您都可以使用Converter 来自定义您的 XML:

DaysOfWeek的注解:

@Root(name = "days")
@Convert(DaysOfWeekConverter.class)
public enum DaysOfWeek
{
    // ...
}

注意:您不再需要@Element@Attribute 注释,该类的xml 的“内容”现在由Converter 指定。

(可能)实现Converter-Interface:

public class DaysOfWeekConverter implements Converter<DaysOfWeek>
{
    @Override
    public DaysOfWeek read(InputNode node) throws Exception
    {
        DaysOfWeek rtn = getDayByColor(node.getAttribute("color").getValue());
        rtn.setMinutes(Integer.valueOf(node.getNext("mins").getValue()));

        return rtn;
    }


    @Override
    public void write(OutputNode node, DaysOfWeek value) throws Exception
    {
        node.setName("days");
        node.setAttribute("color", value.getColor());
        node.getChild("mins").setValue("" + value.getMinutes());
    }


    private DaysOfWeek getDayByColor(String color)
    {
        for( DaysOfWeek value : DaysOfWeek.values() )
        {
            if( value.getColor().equals(color) )
                return value;
        }

        throw new IllegalArgumentException("No Day available for color \'" + color + "\'");
    }
}

(示例) 使用转换器:

/*
 * Setting 'AnnotationStrategy' is requried here - else the Converter will get ignored.
 */
Serializer ser = new Persister(new AnnotationStrategy());

StringWriter sw = new StringWriter();
ser.write(DaysOfWeek.TUESDAY, sw);

// ...

StringReader sr = new StringReader(sw.toString());
DaysOfWeek day = ser.read(DaysOfWeek.class, sr);

// ...

序列化 XML (来自示例)

<days color="yellow">
   <mins>50</mins>
</days>

文档:

【讨论】:

  • 根据构造函数允许值的问题是我无法控制属性与元素中的内容。简单框架的开发人员有stated that,他将对此进行研究,并可能在下一个版本中修复它。为您提供解决方法 +1。