Elim的博客

用来记录一些原创性的总结


Elim

JAXB之XMLEnum和XmlEnumValue

先来看下面这个示例,类EnumObj中定义有一个枚举类型的属性color。那如果需要把EnumObj类型的对象转换为XML,生成的XML会是什么样呢?

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class EnumObj {
	
	private Integer id;
	private Color color;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public Color getColor() {
		return color;
	}
	public void setColor(Color color) {
		this.color = color;
	}
	
}

public enum Color {
	RED,
	BLUE,
	YELLOW;
}

我们使用下面的测试代码来做一个测试:

@Test
public void test() {
	EnumObj obj = new EnumObj();
	obj.setId(1);
	obj.setColor(Color.RED);
	JAXB.marshal(obj, System.out);
}

测试结果如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<enumObj>
    <id>1</id>
    <color>RED</color>
</enumObj>

可能跟大家预期的都差不多,生成的是对应的枚举类型的字符串表示。把XML转换为对象时也是基于枚举类型的字面值进行转换的,验证测试如下。

@Test
public void test() {
	EnumObj obj = new EnumObj();
	obj.setId(1);
	obj.setColor(Color.RED);
	StringWriter writer = new StringWriter();
	JAXB.marshal(obj, writer);
	
	EnumObj obj2 = JAXB.unmarshal(new StringReader(writer.toString()), EnumObj.class);
	assert obj.getId().equals(obj2.getId());
	assert obj.getColor().equals(obj2.getColor());
}

如果希望生成XML的时候不按字面值生成,或者转换的时候不按照字面值进行转换,而是按照自己约定的值进行转换应该怎么办呢?这个时候我们就可以使用@XmlEnum和@XmlEnumValue了。@XmlEnum用于标注在枚举类上,表示其是一个枚举类型。如果你希望生成的Schema中对应的枚举值的定义不是String类型的,则可以通过@XmlEnum的value属性指定类型,比如是int,则可以指定为@XmlEnum(int.class)。@XmlEnumValue用来指定枚举元素值与XML绑定的值。所以如果把Color中的RED用10表示,BLUE用20表示,YELLOW用30表示,则可以进行如下配置。

@XmlEnum(int.class)
public static enum Color {
	@XmlEnumValue("10")
	RED,
	@XmlEnumValue("20")
	BLUE,
	@XmlEnumValue("30")
	YELLOW;
}

配置后生成的XML中Color.RED就被用10来替换了。反之XML转换为对象时,10也会被正确的替换为枚举值RED。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<enumObj>
    <id>1</id>
    <color>10</color>
</enumObj>

(本文由Elim写于2017年8月24日)