博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个JAX-B的例子
阅读量:6834 次
发布时间:2019-06-26

本文共 4818 字,大约阅读时间需要 16 分钟。

  hot3.png

由于wsgen工具在底层使用了JAX-B相关的API包来实现Java与XML之间的类型转换,所以让我们通过一个JAX-B例子来了解一下Java与XML之间是如何转换的。我们创建一个Person类(人)与一个Skier类(滑雪运动员),在每个类定义的起始处都有一个单独的注解,用来说明Java到XML的绑定。Person类被注解为一个@XmlType,而Skier类被注解为一个@XmlRootElement。如下例:

Person.java类:

package ch04.ts;import javax.xml.bind.annotation.XmlType;@XmlTypepublic class Person {	private String name;	private int age;	private String gender;		public  Person() {}	public Person(String name,int age,String gender){		setName(name);		setAge(age);		setGender(gender);	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	public String getGender() {		return gender;	}	public void setGender(String gender) {		this.gender = gender;	}}

Skier.java类:

package ch04.ts;import java.util.Collection;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElementpublic class Skier {	private Person person;	private String national_team;	private Collection
 major_achievements; public Skier(){} public Skier(Person person,String national_team,     Collection
 major_achievements){ setPerson(person); setNational_team(national_team); setMajor_achievements(major_achievements); } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public String getNational_team() { return national_team; } public void setNational_team(String national_team) { this.national_team = national_team; } public Collection
 getMajor_achievements() { return major_achievements; } public void setMajor_achievements(Collection
 major_achievements) { this.major_achievements = major_achievements; }}

@XmlType与@XmlRootElement注解干预了Skier对象的编码(Marshaling),编码是指将一个内存对象(比如一个Skier对象)以一个XML文档形式进行处理的过程,所以,比如说利用网络传输的编码在接收的一端可以被解码(Unmarshal)处理。在通常使用中,编码和解码之间无大的区别,大致等同于序列化/反序列化之间的区别。JAX-B支持将内存中的java对象序列化为XML文档,同时将XML文档反序列化为内存中的java对象。

在Person类中,注解@XmlType表明,JAX-B应该为该java类型产生一个对应XML模式类型。在Skier类中,注解@XmlRootElement表明,JAX-B应该为该Java类产生一个XML文档(最外层的或根元素)。于是,最终产生的XML文档的最外层的根元素用来描述一个skier,同时在skier中有一个嵌套的子元素描述一个person。

对skier进行编码与解码的示例Marshal.java:

package ch04.ts;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.List;import javax.xml.bind.JAXBContext;import javax.xml.bind.JAXBException;import javax.xml.bind.Marshaller;import javax.xml.bind.Unmarshaller;public class Marshal {	private static final String file_name = "bd.xml";	public static void main(String[] args) {		new Marshal().run_example();	}	private void run_example(){		try {			//创建JAXB上下文对象			JAXBContext ctx = JAXBContext.newInstance(Skier.class);			//创建编码器			Marshaller m = ctx.createMarshaller();			//设置为格式化输出			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);			Skier skier = createSkier();			//把对象编码为XML数据使用屏幕输出			m.marshal(skier, System.out);						FileOutputStream out = new FileOutputStream(file_name);			//把对象编码为XML数据输出到文件			m.marshal(skier, out);			out.close();						//创建解码器			Unmarshaller u = ctx.createUnmarshaller();			//把刚才输出到XML的数据再解码为java对象			Skier bd_clone = (Skier) u.unmarshal(new File(file_name));			System.out.println();			//再把对象编码为XML数据输出到屏幕			m.marshal(bd_clone, System.out);		} catch (JAXBException e1) {			e1.printStackTrace();		} catch (FileNotFoundException e2){			e2.printStackTrace();		} catch (IOException e3){			e3.printStackTrace();		}	}	private Skier createSkier(){		Person bd = new Person("Bjoern Daehlie",41,"Male");		List
 list = new ArrayList
(); list.add("12 Olympic Medals"); list.add("9 World Championships"); list.add("Winningest Winter Olympian"); list.add("Greatest Nordic Skier"); return new Skier(bd,"Norway",list); }}

默认情况下,JAX-B编码遵循标准的Java和JavaBean命名规范。比如Skier类的XML标签名称为skier,Person类的XML标签名称是person。针对Skier对象和封装的Person对象,通过调用JavaBean风格的get方法获取对象的相关状态信息,输入到要生成的XML文档中。

遵循JavaBean命名规范的类进行编码和解码时,可以对添加了注解的方法进行重写。然而,一个由wsgen生成的java类并不遵循JavaBean命名规则,请看下面例子:

@XmlRootElement(name = "getTimeAsElapsedResponse",namespace = "http://ts.ch02/")@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "getTimeAsElapsedResponse",namespace = "http://ts.ch02/")public class GetTimeAsElapsedResponse{    @XmlElement(name = "return", namespace = "")    private long _return;    public long get_return(){        return this._return;    }    public void set_return(long _return){        this._return = _return;    }}

注意@XmlAccessorType(XmlAccessType.FIELD)这个注解,它指出字段名称“_return”将被编码和解码,而并没有遵循JavaBean命名规范来定义对应的getter/setter方法对。

另外,通过设定注解属性的其他值,可以覆盖默认的命名约定,如果Skier类中的注解声明修改成如下形式:

@XmlRootElement(name = "NordicSkier")

那么生成的XML文档将会变成:

    .....

注意:JAX-B解码要求每一个类必须拥有一个公开的无参构造方法,用来构造对象。

转载于:https://my.oschina.net/fhd/blog/221073

你可能感兴趣的文章
对象回收时Weak指针自动被置为nil的实现原理
查看>>
php URLEncode() / php URLEncode函数 php urldecode...
查看>>
phpunit mock
查看>>
NodeJS、NPM安装配置步骤(windows版本)
查看>>
mac常用的命令
查看>>
knn 分类
查看>>
【总结】Hadoop中的MultipleOutputs实践
查看>>
测试常见问题
查看>>
SHOP++ 中Hibernate 注解 用法
查看>>
jQuery EasyUI使用教程之创建基本的树网格
查看>>
Fluentd日志处理-插件使用和调试问题(四)
查看>>
实验四 交换机SPAN功能配置 (交换与路由技术)
查看>>
centos7源码安装php5.6并安装pthreads扩展
查看>>
php网络名片系统源码免费电子云名片3.2版
查看>>
SylixOS lite Extension工程开发手册
查看>>
Mysql存储过程从0开始(上)
查看>>
在windows下如何新建爬虫虚拟环境和进行scrapy安装
查看>>
HSRP 技术
查看>>
网络基础~linux路由与网关、路由命令
查看>>
强大的联想4U机架式服务器ThinkSystem SR950
查看>>