XmlRootElement JAXB注解
[XmlRootElement JAXB注解]
Java代码
@Retention(value=RUNTIME)
@Target(value=TYPE)
public @interface XmlRootElement
@Inherited
@Retention(value=RUNTIME)
@Target(value={PACKAGE,TYPE})
public @interface XmlAccessorType
XmlRootElement:
标识这个类或枚举类型是根元素,将会被映射到 XML 元素中。
JAXB中的注解,用来根据java类生成xml内容。 当使用 @XmlRootElement 注释对顶层类或枚举类型进行注释时,类型值被表示为 XML 文档中的 XML 元素。 JAXB Annotation @XmlRootElement // xml 文件的根元素
@XmlElement
将java对象的属性映射为xml的节点。将没有get方法/set方法的属性映射到XML
@XmlAttribute
將ava对象的属性映射为xml的节点的属性。
eleCode
@XmlType(propOrder = { “id”, “name”, “age”,“book”})
指定属性输出顺序。
@XmlElementWrapper(name = “allnames”)
仅允许出现在集合属性上,在原xml结点上再包装一层xml节点。
@XmlAccessorOrder用于对java对象生成的xml元素进行排序。它有两个属性值:
AccessorOrder.ALPHABETICAL:对生成的xml元素按字母书序排序
XmlAccessOrder.UNDEFINED:不排序
@XmlJavaTypeAdaptor:参考Using JAXB 2.0’s XmlJavaTypeAdapter
标识一个接口类型的属性,返回Address接口的一个具体实现类的对象。
@XmlTransient(非瞬态)
用于标示在由Java对象映射XML时,忽略此属性,在生成的XML文件中将不出现此元素。
@XmlAccessorType // 控制默认情况下是否对字段或 Javabean 属性进行系列化。
**默认规则:
** 默认情况下,如果包中不存在 @XmlAccessorType,那么假定使用以下包级别注释。
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
默认情况下,如果类中不存在 @XmlAccessorType注解,并且没有任何超类是使用 @XmlAccessorType 注释的,则假定在类中使用以下默认注释: @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
可能值:
FIELD: 绑定类中的(每个,没有get方法/set方法的属性也可以)非静态、非瞬态字段将会自动绑定映射到 XML,除非由 XmlTransient 注释。
NONE: 所有字段或属性都不能绑定到 XML,除非使用一些 JAXB 注释专门对它们进行注释。
PROPERTY: 绑定类中的(每个,只有有get方法/set方法的属性才可以)自动绑定映射到 XML,除非由 XmlTransient 注释。
PUBLIC_MEMBER:每个公共获取方法/设置方法对和每个公共字段将会自动绑定到 XML,除非由 XmlTransient 注释。
XmlElement和@XmlAttribute区别描述
@XmlElement将java对象的属性映射为xml的节点。
@XmlAttribute將ava对象的属性映射为xml的节点的属性。
package jaxb;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessType;
@XmlRootElement // 必须要标明这个元素
@XmlAccessorType(XmlAccessType.FIELD)
public class Boy {
String name = “CY”;
}
package jaxb;
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class JAXBTest {
public static void main(String[] args) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(Boy.class);
Marshaller marshaller = context.createMarshaller();
Unmarshaller unmarshaller = context.createUnmarshaller();
Boy boy = new Boy();
marshaller.marshal(boy, System.out);
System.out.println();
String xml = "David ";
Boy boy2 = (Boy) unmarshaller.unmarshal(new StringReader(xml));
System.out.println(boy2.name);
} }
执行结果:
CY
David (先 是marshall成 xml文件,再是把 xml 文件 unmarshal 成 java object。)
改动一:
修改@XmlAccessorType(XmlAccessType.FIELD) --> @XmlAccessorType(XmlAccessType.PROPERTY) 意思是只有 属性 才能被转换成 xml 中的标签。
所以再运行的结果是: CY 就是说 java object 转换成 xml 的时候,name 不是属性(因为没有 get set方法),所以name不转换成标签。
改动二:
在 改动一 的基础上,给name属性添加 get set 方法。
再运行,结果为:
CY
David 由 此 可见 @XmlAccessorType 这个annotation 的作用。
改动三:
在改动二 的基础上,给Boy 再添加一个field, int age=10, 即:
package jaxb;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessType;
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Boy {
String name = “CY”;
int age = 10;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} }
显然,这个age 是不会被 转化 到xml 文件中的。
解决办法是:
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessType;
@XmlRootElement // bixude
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Boy {
String name = "CY";
@XmlElement
int age = 10;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
加上 @XmlElement annotation. 运行结果为:
private String name = "CY";
private Address address; // 是一个接口
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在 java object 转换成 xml 的时候,接口Address 无法被转换。
所以 这里要加上 @XmlJavaTypeAdapter(AddressAdapter.class)
所以 要多写一个AddressAdaptor 类。这个类会返回Address接口的一个具体实现类的对象。
这 就是 @XmlJavaTypeAdapter 的作用
@XmlType注解标注xml生成顺序
默认情况下,Jaxb编组出来的xml中的字段顺序是随机的,你可以使用@XmlType的propOrder属性
来指定序列化的顺序。
第一步:定义java类时,使用@XmlType(propOrder = { “id”, “name”, “age”,“book”})指定属性输出顺序。
Java代码
package step2;
import java.util.Set;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement
@XmlType(propOrder = { “id”, “name”, “age”,“book”})
public class Customer {
String name;
int age;
int id;
Set book;
@XmlElement(name=“name”)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement(name=“age”)
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@XmlElement(name=“id”)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return “Customer [id=” + id + “,name=” + name + “,age=” + age + “,book=” + book + “]”;
}
@XmlElementWrapper(name=“books”)
@XmlElement(name=“book”)
public Set getBook() {
return book;
}
public void setBook(Set book) {
this.book = book;
}
}
输出的xml:
Xml代码
@XmlElementWrapper注解表示生成一个包装器元素。该注释支持两种形式的序列化。
注意: @XmlElementWrapper仅允许出现在集合属性上。
第一步:定义将要转化的Java对象
注
package jijian.test;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Customer {
String[] names;
int age;
int id;
//使用@XmlElementWrapper注解后,将会在原xml结点上再包装一层xml节点
@XmlElementWrapper(name = "allnames")
@XmlElement(name = "myname")
public String[] getNames() {
return names;
}
public void setNames(String[] names) {
this.names = names;
}
@XmlElement
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Customer [id = " + id + ",names = " + names + ",age = " + age + "]";
}
}
第二步: 生成xml文件并写入文件
package jijian.test;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class Object2XmlDemo {
public static void main(String[] args) throws JAXBException {
Customer customer = new Customer();
customer.setId(100);
customer.setNames(new String[]{"name-a","name-b","name-c"});
customer.setAge(25);
File file = new File("D:\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(customer , file);
jaxbMarshaller.marshal(customer, System.out);
}
}
生成的xml:
25 name-a name-b name-c这个示范代码生成的xml同时写入了文件和标准输出(控制台):
XmlElement和@XmlAttribute区别描述
@XmlElement将java对象的属性映射为xml的节点,在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。eg:@XmlElement该属性作为xml的element,且可以增加属性(name=“NewElementName”),那么生成的xml串的elment的标签是NewElementName
@XmlAttribute將被序列化为xml节点中的属性
证明
使用@XmlElement,并且带有name属性,修改生成的xml标签
package test.bean;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name=“rootclass”)
public class RootClass {
private EleClassA a;
private EleClassB b;
private String root;
private String rootA;
@XmlElement(name=“eleClassA”)
public EleClassA getA() {
return a;
}
public void setA(EleClassA a) {
this.a = a;
}
@XmlElement(name=“EleclassA”)
public EleClassB getB() {
return b;
}
public void setB(EleClassB b) {
this.b = b;
}
public String getRoot() {
return root;
}
public void setRoot(String root) {
this.root = root;
}
public String getRootA() {
return rootA;
}
public void setRootA(String rootA) {
this.rootA = rootA;
}
}
使用@XmlElement,并且不带有name属性
package test.bean;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
public class EleClassA {
private String eleA;
private String eleB;
private String attrC;
@XmlElement
public String getEleA() {
return eleA;
}
public void setEleA(String eleA) {
this.eleA = eleA;
}
@XmlElement(name=“elebnewname”)
public String getEleB() {
return eleB;
}
public void setEleB(String eleB) {
this.eleB = eleB;
}
@XmlAttribute
public String getAttrC() {
return attrC;
}
public void setAttrC(String attrC) {
this.attrC = attrC;
}
}
使用@XmlAttribute
package test.bean;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
public class EleClassB {
private String attrUserName;
private String attrPassword;
private String eleCode;
@XmlAttribute
public String getAttrUserName() {
return attrUserName;
}
public void setAttrUserName(String attrUserName) {
this.attrUserName = attrUserName;
}
@XmlAttribute(name=“password”)
public String getAttrPassword() {
return attrPassword;
}
public void setAttrPassword(String attrPassword) {
this.attrPassword = attrPassword;
}
@XmlElement
public String getEleCode() {
return eleCode;
}
public void setEleCode(String eleCode) {
this.eleCode = eleCode;
}
运行Test1类中main方法,执行结果:
package test;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import test.bean.EleClassA;
import test.bean.EleClassB;
import test.bean.RootClass;
public class Test1 {
public static void main(String[] args) {
RootClass rc = new RootClass();
EleClassA a = new EleClassA();
EleClassB b = new EleClassB();
a.setAttrC(“attrc”);
a.setEleA(“eleA”);
a.setEleB(“eleB”);
b.setAttrPassword(“attrPassword”);
b.setAttrUserName(“attrUsrName”);
b.setEleCode(“eleCode”);
rc.setA(a);
rc.setB(b);
rc.setRoot(“root”);
rc.setRootA(“rootA”);
JAXBContext context;
try {
context = JAXBContext.newInstance(RootClass.class);
Marshaller mar = context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
mar.setProperty(Marshaller.JAXB_ENCODING, “UTF-8”);
StringWriter writer = new StringWriter();
mar.marshal(rc, writer);
System.out.println(writer.toString());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
eleA
eleB
eleCode
root
rootA
总结:
可以看出EleClassA这个类中,attrc上使用标签@XmlAttribute,在xml中北设置为eleClassA元素的属性。
在RootClass类中,geta上使用注解@XmlElement(name=“eleClassA”),在xml中变成了标签,其他的类似,可以看着类上的代码对比结果,来理解两者之间的区别。