XML-JAXB

Jaxb

这是一个Java自带的工具类模块,用于XML和对象之间的相互转换。

核心类
  • JAXBContext类,是应用的入口,用于管理XML和JavaBean之间的绑定信息;
  • Marshaller接口,用于将Java对象序列化为XML;
  • Unmarshaller接口,用于将XML反序列化为Java对象。
核心注解
  • @XmlRootElement,用于类级别的注解,对应于xml的根元素;
  • @XmlElement,用于类中属性的注解,对应于xml中的节点元素;
  • @XmlElementWrapper,用于数组或集合类属性的注解,对应于xml中数组类元素的包裹节点,一般与@XmlElement一起使用;
  • @XmlAttribute,用于Java对象中属性的注解,对应于xml中该对象节点的属性元素;
  • @XmlAccessorType,用于类级别的注解,表示Java对象的哪种类型的属性自动序列化;
  • @XmlAccessorOrder,用于类级别的注解,用于对xml的节点顺序进行控制;
  • @XmlType,用于类级别的注解,主要用于实现对象映射为xml时的节点顺序控制;
  • @XmlTransient,用于Java对象中属性的注解,表示注解的属性不参与序列化;
代码示例

1.基本示例–JavaBean to XML
示例JavaBean

@XmlRootElement(name="student")
public class Student {

	@XmlElement(name="name")
	private String name;

	@XmlElement(name="address")
	private String address;
	
	// 省略get/set方法
	...
}

JavaBean 映射为Xml的示例

public class Demo {
	public static void main(String[] args) throws JAXBException {
		Student student = new Student();
		student.setName("小明");
		student.setAddress("花果山");
		
		// 实例化JAXBContext作为应用入口
		JAXBContext jaxbContext = JAXBContext.newInstance(Student.class);
		// 创建Marshaller对象,用于实现JavaBean映射为XML
		Marshaller marshaller = jaxbContext.createMarshaller();
		// 设置xml的编码格式,默认为utf-8
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
        // 设置是否省略xm头声明信息
	    marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);
        // 设置xml是否格式化输出
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

		// 创建字符串Writer,用于生成XML字符串
        StringWriter writer = new StringWriter();
        marshaller.marshal(student, writer);

        String str = writer.toString();
        System.out.println(str);
	}
}

2.基本示例–XML to JavaBean
使用上面示例的Student类。

public class Demo {
		public static void main(String[] args) throws JAXBException {
			String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?><student><name>小明</name><address>花果山</address></student>";
			
			// 应用的入口,用于管理XML/Java绑定信息
            JAXBContext jaxbContext = JAXBContext.newInstance(Root.class);
            // Unmarshaller接口,将XML数据反序列化为Java对象
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

            Student student = (Student ) unmarshaller.unmarshal(new StringReader(xml));

            System.out.println(root.toString());
		}
	}	

3.特殊注解示例
3.1 @XmlElementWraper
这个注解用于对数组类或集合类属性进行注解。

	@XmlRootElement
	public class school {
		
		@XmlElementWrapper(name="students")
		@XmlElement(name="student")
		private List<Student> students;
		
		// 省略get/set方法
		...
	}

上面JavaBean映射出的XML格式如下:

<school>
	<students>
		<student>
			<name>小明</name>
			<address>花果山</address>
		</student>
		<student>
			<name>小红</name>
			<address>花果山</address>
		</student>
	</students>
</school>

如果没有使用@XmlElementWrapper注解,数组节点会平铺在父节点下。上面的实体映射成的XML示例如下:

<school>
	<student>
		<address>花果山</address>
		<name>小明</name>
	</student>
	<student>
		<address>花果山</address>
		<name>小红</name>
	</student>
</school>

3.2 @XmlAttribute
这个是用于给节点元素添加属性。据我目前了解,使用起来不方便。示例入下:

@XmlRootElement
public void Teacher {
	
	@XmlElement
	private String name;

	@XmlAttribute
	private String version = "1.0";
		
	// 省略get/set方法
	...
}

Teacher类映射的Xml示例如下:

<teacher version="1.0">
	<name>李雷</name>
</teacher>

为什么说使用起来不方便呢?因为@XmlAttribute只能用于给所属类对应的节点添加属性,而不能给所属类中参数也添加属性。在参数也具有属性时,就必须要将这个参数独立作为一个实体类,才能给这个参数添加属性。示例如下:

@XmlRootElement
public class Age {
	@XmlValue
	private Integer value;
	
	@XmlAttribute
	private String attr="integer";
	
	// 省略get/set方法
	...
}

@XmlRootElement
public class Person {
	
	@XmlElement(name="age")
	private Age age;

	@XmlAttribute
	private String attr = "男";
	
	// 省略get/set方法
	...
}

上面代码的Xml映射结果示例如下:

<person attr="">
	<age attr="integer">18</age>
</person>

在这里使用了@XmlValue注解,这个注解是用于给一个节点元素添加值,详情下面再说。如果一个Xml中有很多叶子节点,都具有属性,那么就需要给这个叶子节点都创建一个实体类,使用起来就很不方便,零碎的小类会很多。

3.3 @XmlAccessorType
这个注解作用于类,控制了是否自动将JavaBean的参数或属性与Xml绑定。它的属性值有4个枚举值:

  • XmlAccessType.PROPERTY:JavaBean中所有具有getter/setter对的成员变量自动与XML绑定;
  • XmlAccessType.FIELD:JavaBean中的所有非静态的、非瞬时的参数域自动与XML绑定;
  • XmlAccessType.PUBLIC_MEMBER:JavaBean中具有的public修饰的getter/setter对和每个public参数都会自动与XML绑定;
  • XmlAccessType.NONE:JavaBean中的参数除非被特别添加注解,否则不会与XML绑定。
    示例如下:
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlRootElement
public class Company {
	private String name;
	private String address;
	private String owner;

	public String getName() {
		return this.name;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	public void setOwner(String owner) {
		this.owner = owner;
	}
}

在这个示例中,Company有三个成员变量,其中name具有完整的getter/setter方法对,address没有getter/setter方法,owner只有setter方法。这个类映射为Xml的结果如下:

<company>
	<name>小明与小红科技有限公司</name>
</company>

其余三种注解的示例可以类推。
3.4 @XmlAccessorOrder
这个注解作用于类,用于控制JavaBean映射为Xml时的节点顺序。属性值有两个:

  • XmlAccessOrder.UNDEFINED:顺序未定义,默认按照J字母顺序进行排列;
  • XmlAccessOrder.ALPHABETICAL:按照字母顺序进行排列。
    如果不使用该注解,节点顺序也是按照字母顺序排列。
    示例如下
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Country {
	private String name;
	private String address;
	// 省略getter/setter方法
}

映射的XML为:

<country>
	<address>北纬34度,东经120度</address>
	<name>神秘国</name>
</country>

3.5 @XmlType
该注解作用于类,主要用于自定义Xml节点顺序。示例如下:

@XmlType(propOrder={"size", "name", "address"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Classroom {
	private String name;
	private String address;
	private Integer size;
	// 省略getter/setter方法
}

生成的Xml示例如下:

<Classroom>
	<size>120</size>
	<name>小明的教室</name>
	<address>A栋3楼</address>
</Classroom>

在使用@XmlType自定义顺序时,@XmlAccessorOrder作用被覆盖。
3.6 @XmlTransient
该注解用于类、成员变量、方法,用于标注该类/成员变量/方法不与Xml进行绑定。示例如下;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Restaurant {
	private String name;
	@XmlTransient
	private String address;
	// 省略getter/setter
}

生成的Xml示例如下:

<Restaurant>
	<name>小明的餐馆</name>
</Restaurant>

4 监听器
Jaxb定义了一个监听器接口Marshaller.Listener,可以在对象进行序列化之前和之后处理自定义的事件。
一个Marshaller只能设置一个监听器。

public class CustomListener implements Marshaller.Listener {
	@Override
    public void beforeMarshal(Object source) {
	    super.beforeMarshal(source);
    }
	@Override
    public void afterMarshal(Object source) {
        super.afterMarshal(source);
    }
}

在使用时,示例如下:

JAXBContext jaxbContext = JAXBContext.newInstance(Student.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setListener(new CustomListener());
...

5 schema
使用xjc命令可以根据schema文件生成JavaBean;
在JavaBean与Xml相互转换时,也可以使用schema进行参数类型校验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值