赞
踩
一、code
- @Test
- public void marshalTest() {
- try {
- JAXBContext jContext = JAXBContext.newInstance(User.class);
- Marshaller marshaller = jContext.createMarshaller();
- Pet pet = new Pet("dog","小哈");
- Book aBook = new Book("平凡的世界", 20);
- Book bBook = new Book("明晓溪",15);
- List<Book> books = new ArrayList<Book>();
- books.add(aBook);
- books.add(bBook);
- User user = new User("张三","女", 20, new Date(), null, pet, books);
- //设置生成的xml的编码
- marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
- //设置生成的xml内容是否format,否的话是显示一行
- marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- //是否省略头部声明信息,默认false
- marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
- //直接输出文件
- marshaller.marshal(user, new File("a.xml"));
-
- OutputStream out = new ByteArrayOutputStream();
- //输出字节流
- marshaller.marshal(user, out);
- System.out.println("========"+out.toString());
- } catch (JAXBException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
JDK1.7及之后做了更多封装,更加简单:
JAXB.marshal(user, new File("b.xml"));
- @Test
- public void unmarshallTest() {
- try {
- JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
- Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
- User user = (User) unmarshaller.unmarshal(new File("a.xml"));
- System.out.println(user.toString());
-
- } catch (JAXBException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
1.7及之后:
User user2 = JAXB.unmarshal(new File("b.xml"), User.class);
二、重要注解
- //根元素默认类名首字母小写。设置name后,map到name。设置namespace后,生成到的根元素-><ns2:person xmlns:ns2="com">
- @XmlRootElement(name="person",namespace="com")
- public class User{
- @XmlElement(name="name1")//此注解用于属性与xml元素到map。可加在属性上(private的会报错),或get/set方法上。
- @XmlElement(name=""namespace="com1")//设置后,根元素-><ns3:person xmlns:ns2="com1" xmlns:ns3="com">,对应元素-><ns2:sex>女</ns2:sex>
- @XmlElement(nillable=true)//默认null值不显示在xml中,此设置为true,则null值也显示-><other xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
- @XmlElement(required=true)?????
- @XmlElement(defaultValue="others")????
加载类属性上,默认是设置root的属性,可设置namepace和required属性等
用于映射直接应用XML元素的文本内容的
用于定义在类上,表示该类对应于XML的一个复杂类型对象。默认情况下不加XmlType时我们的类也会自动的被映射为XML的一个复杂类型对象。使用@XmlType时主要是希望通过它的propOrder属性指定生成的XML的属性排列顺序,不指定顺序时默认生成的XML的节点/属性的顺序是不确定的
如:@XmlType(propOrder= { "name", "age"})
也是指定Java对象生成的XML元素/属性的顺序的。通过它指定的顺序的可选值有:
XmlAccessOrder.ALPHABETICAL:按照字母的自然顺序进行升序排列。
XmlAccessOrder.UNDEFINED:未定义,即顺序不固定,这个是默认值。
除了可以定义在类上,还可以定义在包上,定义在包上表示在该包中所有的类型对应的XML的默认排序规则。定义在包中时需要在对应的包下面建立package-info.java文件,然后将该注解加在package-info.java中的package声明上。如下我们就在com.xxx.jaxb的package-info.java中指定了com.xxx.jaxb包中的类对应的XML元素顺序默认按照字母升序排列。
- @javax.xml.bind.annotation.XmlAccessorOrder(javax.xml.bind.annotation.XmlAccessOrder.ALPHABETICAL)
- package com.xxx.jaxb;
用于在进行Java对象和XML相互转换时定义需要忽略的Java属性。
可以标注在Class和package上,标注在package上时需要标注在对应的package-info.java文件的package上。
作用:指定Java对象和XML相互转换时Java对象属性访问方式,即哪些属性会与XML进行映射。它的可选值是由XmlAccessType类型的枚举指定。一共四种:
用于进行集合类型的属性映射时,在XML元素的外层再多包一层元素。可以指定name属性外,还可以指定namespace、required和nilable属性。
- @XmlRootElement
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Root {
-
- private List<String> values = Arrays.asList("A", "B", "C");
-
- }
生成的xml
- <root>
- <values>A</values>
- <values>B</values>
- <values>C</values>
- </root>
设置xmlElementWrapper:
- @XmlRootElement
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Root {
-
- @XmlElementWrapper
- @XmlElement(name="value")
- private List<String> values = Arrays.asList("A", "B", "C");
包裹后的xml
- <root>
- <items>
- <value>A</value>
- <value>B</value>
- <value>C</value>
- </items>
- </root>
用于自定义javabean和xml间字段转换的规则,比如date转为字符串,转为什么格式的等。
使用XmlJavaTypeAdapter时需要通过value属性指定一个XmlAdapter类,表示对应的适配器类。XmlAdapter是一个抽象类。其中定义了两个方法,marshal和unmarshal,marshal方法用于适配从Java到XML,unmarshal方法用于适配从XML到Java。比如需要把java.util.Date类型转换为yyyy-MM-dd格式的字符串可以定义如下适配器。
- //适配器定义:
- public class DateAdapter extends XmlAdapter<String, java.util.Date> {
-
- private static final String PATTERN = "yyyy-MM-dd";
-
- @Override
- public Date unmarshal(String v) throws Exception {
- if (v != null) {
- return new SimpleDateFormat(PATTERN).parse(v);
- }
- return null;
- }
-
- @Override
- public String marshal(Date v) throws Exception {
- if (v != null) {
- return new SimpleDateFormat(PATTERN).format(v);
- }
- return null;
- }
-
- }
- //适配器使用:
-
- @XmlRootElement
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Root {
-
- @XmlJavaTypeAdapter(DateAdapter.class)//value=DateAdapter.class
- private Date date = new Date();
-
- }
xml输出:
- <root>
- <date>2017-11-19</date>
- </root>
XmlJavaTypeAdapter也可以标注在Java类上,表示遇到对应的类型时就使用指定的适配器
XmlJavaTypeAdapter也可以标注在package上,标注在package上时必须指定type类型,表示在指定的包中遇到type属性指定的类型时就使用value属性对应的适配器。下面的代码表示在com.xxx.jaxb中遇到java.util.Date类型就使用DateAdapter适配器。
- @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value=DateAdapter.class, type=java.util.Date.class)
- package com.xxx.jaxb;
只能标注在package上,用于定义多个XmlJavaTypeAdapters
- @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters({
- @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value = DateAdapter.class, type = java.util.Date.class),
- @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value = MoneyAdapter.class, type = java.math.BigDecimal.class) })
- package com.xxx.jaxb;
用于不固定节点,如果有很多,可以用list<Object>来接收,默认创建的都是org.w3c.dom.Element类型的对象。动态节点有些是固定类型,可以设置@XmlAnyElement时指定其lax属性为true
- @XmlRootElement
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Root {
-
- public String no;
- public String name;
- @XmlAnyElement
- public List<Object> others;
-
- }
-
-
- @XmlRootElement
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Root {
-
- public String no;
- public String name;
- @XmlAnyElement(lax=true)
- public List<Object> others;
-
- @XmlRootElement(name="d1")
- @XmlAccessorType(XmlAccessType.FIELD)
- public static class D1 {
- @XmlValue
- public String value;
- }
- }
这样进行了unmarshal之后对应的others属性中就包含了一个D1类型的对象
- @Test
- public void testBasicUnmarshal() throws Exception {
- JAXBContext jaxbContext = JAXBContext.newInstance(Root.class, D1.class);
- Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
- Root root = (Root) unmarshaller.unmarshal(this.getClass().getClassLoader().getResourceAsStream("jaxb/dynamic.xml"));
- D1 d1 = null;
- for (Object obj : root.others) {
- if (obj instanceof D1) {
- d1 = (D1) obj;
- }
- }
- Assert.assertNotNull(d1);
- }
用于定义多个@XmlElement的,标注在集合类型的属性上以根据集合元素类型给定不同的元素名称。
- @XmlRootElement
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Root {
-
- @XmlElementWrapper(name = "objs")
- @XmlElements({ @XmlElement(name = "string", type = String.class), @XmlElement(name = "int", type = Integer.class),
- @XmlElement(name = "boolean", type = Boolean.class), @XmlElement(name = "long", type = Long.class) })
- public List<Object> objs = Arrays.asList("A", 1, true, 1L);
- }
http://doc.okbase.net/234390216/archive/296027.html
XML Schema类型 | Java数据类型 |
xsd:string | java.lang.String |
xsd:positiveInteger | java.math.BigInteger |
xsd:int | int |
xsd:long | long |
xsd:short | short |
xsd:decimal | java.math.BigDecimal |
xsd:float | float |
xsd:double | double |
xsd:boolean | boolean |
xsd:byte | byte |
xsd:QName | javax.xml.namespace.QName |
xsd:dateTime | javax.xml.datatype.XMLGregorianCalendar |
xsd:base64Binary | byte[] |
xsd:hexBinary | byte[] |
xsd:unsignedInt | long |
xsd:unsignedShort | int |
xsd:unsignedByte | short |
xsd:time | javax.xml.datatype.XMLGregorianCalendar |
xsd:date | javax.xml.datatype.XMLGregorianCalendar |
xsd:g | javax.xml.datatype.XMLGregorianCalendar |
xsd:anySimpleType | java.lang.Object |
xsd:anySimpleType | java.lang.String |
xsd:duration | javax.xml.datatype.Duration |
xsd:NOTATION | javax.xml.namespace.QName |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。