zoukankan      html  css  js  c++  java
  • Java对象和XML的相互转换化

    https://blog.csdn.net/u010331823/article/details/78258311

    写在前面:Jaxb是JavaEE的规范.全称Java Architecture for XML Binding.  可以根据XML Schema产生Java类的技术.JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档.  JAXB 2.0是JDK 1.6的组成部分。JAXB 2.2.3是JDK 1.7的组成部分,在实际使用不需要引入新的jar.

    1. 常用注解说明
    常用的annotation有:
    @XmlType
    @XmlElement
    @XmlRootElement
    @XmlAttribute
    @XmlAccessorType
    @XmlAccessorOrder
    @XmlTransient
    @XmlJavaTypeAdapter
    @Temporal(TemporalType.XXXX) -->JPA中的时间处理注解,非JAXB
    @XmlElementWrapper

    1.@XmlType
      @XmlType用在class类的注解,常与@XmlRootElement,@XmlAccessorType一起使用。它有三个属性:name、propOrder、namespace,经常使用的只有前两个属性。如:
    同时使用了@XmlType(propOrder={})和@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)的时候,生成的xml只按照propOrder定义的顺序生成元素
    @XmlType(name = "basicStruct", propOrder = {
        "intValue",
        "stringArray",
        "stringValue"
    )
    在使用@XmlType的propOrder 属性时,必须列出JavaBean对象中的所有属性,否则会报错。

    2.@XmlRootElement
      @XmlRootElement用于类级别的注解,对应xml的跟元素,常与 @XmlType 和 @XmlAccessorType一起使用。如:
      @XmlType
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlRootElement
      public class Address {}

    3.@XmlElement
      @XmlElement将java对象的属性映射为xml的节点,在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。如:
      @XmlElement(name="Address")  
      private String yourAddress;

    4.@XmlAttribute
      @XmlAttribute用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。如:
      @XmlAttribute(name="Country")
      private String state;
     
    5.@XmlAccessorType
      @XmlAccessorType用于指定由java对象生成xml文件时对java对象属性的访问方式。常与@XmlRootElement、@XmlType一起使用。它的属性值是XmlAccessType的4个枚举值,分别为:

    XmlAccessType.FIELD:java对象中的所有成员变量
    XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量
    XmlAccessType.PUBLIC_MEMBER:java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量
    XmlAccessType.NONE:java对象的所有属性都不映射为xml的元素
    注意:@XmlAccessorType的默认访问级别是XmlAccessType.PUBLIC_MEMBER,因此,如果java对象中的private成员变量设置了public权限的getter/setter方法,就不要在private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成xml时会报同一个属性在java类里存在两次的错误。同理,如果@XmlAccessorType的访问权限为XmlAccessType.NONE,如果在java的成员变量上使用了@XmlElement或@XmlAttribute注解,这些成员变量依然可以映射到xml文件。

    注意:虽然@XmlAccessorType为XmlAccessType.NONE,但是在java类的私有属性上加了@XmlAttribute和@XmlElement注解后,这些私有成员会映射生成xml的元素

    6.@XmlAccessorOrder
      @XmlAccessorOrder用于对java对象生成的xml元素进行排序。它有两个属性值:
      AccessorOrder.ALPHABETICAL:对生成的xml元素按字母书序排序
      XmlAccessOrder.UNDEFINED:不排序

    7.@XmlTransient
      @XmlTransient用于标示在由java对象映射xml时,忽略此属性。即,在生成的xml文件中不出现此元素。

    8.@XmlJavaTypeAdapter
      @XmlJavaTypeAdapter常用在转换比较复杂的对象时,如map类型或者格式化日期等。使用此注解时,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法。
      @XmlJavaTypeAdapter(value=xxx.class),value为自己定义的adapter类
      XmlAdapter 抽象接口如下:

    public abstract class XmlAdapter<ValueType,BoundType> {    // Do-nothing constructor for the derived classes.
        protected XmlAdapter() {}
        // Convert a value type to a bound type.
        public abstract BoundType unmarshal(ValueType v);
        // Convert a bound type to a value type.
        public abstract ValueType marshal(BoundType v);
     }

    下面举一个简单的例子:

    1.School类 一些基本的属性,包含Student集合

    package com.gs.mountain.test.xml;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    import java.util.ArrayList;
    import java.util.List;
    @XmlRootElement(name="list")
    public class School {
    private String name;
    private String address;
    private String level;
    private long popular;
    private List<Student> students=new ArrayList<Student>();
    @XmlElement(name = "name")
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    @XmlElement(name = "address")
    public String getAddress() {
    return address;
    }
    public void setAddress(String address) {
    this.address = address;
    }
    @XmlElement(name = "level")
    public String getLevel() {
    return level;
    }
    public void setLevel(String level) {
    this.level = level;
    }
    @XmlElement(name = "popular")
    public long getPopular() {
    return popular;
    }
    public void setPopular(long popular) {
    this.popular = popular;
    }
    @XmlElement(name = "Student")
    public List<Student> getStudents() {
    return students;
    }
    public void setStudents(List<Student> students) {
    this.students = students;
    }
    }
    2.Student类,包含爱好集合和一些基本的属性

    package com.gs.mountain.test.xml;

    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlElementWrapper;
    import java.util.List;

    public class Student {
    String name; //姓名
    String sex; //性别
    int number; //学号
    String className; //班级
    List<String> hobby; //爱好

    public Student(){
    }
    public Student(String name,String sex,int number,
    String className,List<String> hobby) {
    this.name = name;
    this.sex = sex;
    this.number = number;
    this.className = className;
    this.hobby = hobby;
    }
    @XmlAttribute(name="name")
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }

    @XmlAttribute(name="sex")
    public String getSex() {
    return sex;
    }
    public void setSex(String sex) {
    this.sex = sex;
    }

    @XmlAttribute(name="number")
    public int getNumber() {
    return number;
    }
    public void setNumber(int number) {
    this.number = number;
    }

    @XmlElement(name="className")
    public String getClassName() {
    return className;
    }
    public void setClassName(String className) {
    this.className = className;
    }

    @XmlElementWrapper(name="hobbys")
    @XmlElement(name = "hobby")
    public List<String> getHobby() {
    return hobby;
    }
    public void setHobby(List<String> hobby) {
    this.hobby = hobby;
    }

    }
    3.工具类,提供xml到javaBean的相互转换 由 valvin大神提供,很好用(自己看其中的方法,说不定有你需要的)

    /**
    * Copyright (c) 2005-2012 springside.org.cn
    */
    package com.gs.mountain.common.mapper;

    import java.io.StringReader;
    import java.io.StringWriter;
    import java.util.Collection;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ConcurrentMap;

    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBElement;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    import javax.xml.bind.annotation.XmlAnyElement;
    import javax.xml.namespace.QName;

    import com.gs.mountain.common.utils.StringUtils;
    import org.springframework.http.converter.HttpMessageConversionException;
    import org.springframework.util.Assert;

    import com.gs.mountain.common.utils.Exceptions;
    import com.gs.mountain.common.utils.Reflections;

    /**
    * 使用Jaxb2.0实现XML<->Java Object的Mapper.
    *
    * 在创建时需要设定所有需要序列化的Root对象的Class.
    * 特别支持Root对象是Collection的情形.
    *
    * @author calvin
    * @version 2013-01-15
    */
    @SuppressWarnings("rawtypes")
    public class JaxbMapper {

    private static ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>();

    /**
    * Java Object->Xml without encoding.
    */
    public static String toXml(Object root) {
    Class clazz = Reflections.getUserClass(root);
    return toXml(root, clazz, null);
    }

    /**
    * Java Object->Xml with encoding.
    */
    public static String toXml(Object root, String encoding) {
    Class clazz = Reflections.getUserClass(root);
    return toXml(root, clazz, encoding);
    }

    /**
    * Java Object->Xml with encoding.
    */
    public static String toXml(Object root, Class clazz, String encoding) {
    try {
    StringWriter writer = new StringWriter();
    createMarshaller(clazz, encoding).marshal(root, writer);
    return writer.toString();
    } catch (JAXBException e) {
    throw Exceptions.unchecked(e);
    }
    }

    /**
    * Java Collection->Xml without encoding, 特别支持Root Element是Collection的情形.
    */
    public static String toXml(Collection<?> root, String rootName, Class clazz) {
    return toXml(root, rootName, clazz, null);
    }

    /**
    * Java Collection->Xml with encoding, 特别支持Root Element是Collection的情形.
    */
    public static String toXml(Collection<?> root, String rootName, Class clazz, String encoding) {
    try {
    CollectionWrapper wrapper = new CollectionWrapper();
    wrapper.collection = root;

    JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>(new QName(rootName),
    CollectionWrapper.class, wrapper);

    StringWriter writer = new StringWriter();
    createMarshaller(clazz, encoding).marshal(wrapperElement, writer);

    return writer.toString();
    } catch (JAXBException e) {
    throw Exceptions.unchecked(e);
    }
    }

    /**
    * Xml->Java Object.
    */
    @SuppressWarnings("unchecked")
    public static <T> T fromXml(String xml, Class<T> clazz) {
    try {
    StringReader reader = new StringReader(xml);
    return (T) createUnmarshaller(clazz).unmarshal(reader);
    } catch (JAXBException e) {
    throw Exceptions.unchecked(e);
    }
    }

    /**
    * 创建Marshaller并设定encoding(可为null).
    * 线程不安全,需要每次创建或pooling。
    */
    public static Marshaller createMarshaller(Class clazz, String encoding) {
    try {
    JAXBContext jaxbContext = getJaxbContext(clazz);

    Marshaller marshaller = jaxbContext.createMarshaller();

    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

    if (StringUtils.isNotBlank(encoding)) {
    marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
    }

    return marshaller;
    } catch (JAXBException e) {
    throw Exceptions.unchecked(e);
    }
    }

    /**
    * 创建UnMarshaller.
    * 线程不安全,需要每次创建或pooling。
    */
    public static Unmarshaller createUnmarshaller(Class clazz) {
    try {
    JAXBContext jaxbContext = getJaxbContext(clazz);
    return jaxbContext.createUnmarshaller();
    } catch (JAXBException e) {
    throw Exceptions.unchecked(e);
    }
    }

    protected static JAXBContext getJaxbContext(Class clazz) {
    Assert.notNull(clazz, "'clazz' must not be null");
    JAXBContext jaxbContext = jaxbContexts.get(clazz);
    if (jaxbContext == null) {
    try {
    jaxbContext = JAXBContext.newInstance(clazz, CollectionWrapper.class);
    jaxbContexts.putIfAbsent(clazz, jaxbContext);
    } catch (JAXBException ex) {
    throw new HttpMessageConversionException("Could not instantiate JAXBContext for class [" + clazz
    + "]: " + ex.getMessage(), ex);
    }
    }
    return jaxbContext;
    }

    /**
    * 封装Root Element 是 Collection的情况.
    */
    public static class CollectionWrapper {

    @XmlAnyElement
    protected Collection<?> collection;
    }

    }

    4.下面是测试的代码,结果很棒,so easy!


    package com.gs.mountain.test.xml;

    import com.gs.mountain.common.mapper.JaxbMapper;

    import javax.xml.bind.JAXBException;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;

    public class BeanToXml {

    public static void main(String[] args) throws JAXBException, IOException {
    List<String> hobby = new ArrayList();
    hobby.add("篮球");
    hobby.add("音乐");
    hobby.add("乒乓球");

    List<Student> studentList = new ArrayList();

    Student st = new Student("张三","男",10001,"尖子班",hobby);
    studentList.add(st);
    Student st1 = new Student("李四","男",10002,"普通班",hobby);
    studentList.add(st1);
    Student st2 = new Student("莉莉","女",10003,"普通班",hobby);
    studentList.add(st2);

    School school = new School();
    School school1 ;
    School school2 ;
    school.setAddress("成都市武侯区天府五街");
    school.setLevel("高级中学");
    school.setName("华阳中学");
    school.setPopular(5000L);
    school.setStudents(studentList);
    school1=school;
    school2=school;
    List<School> listSchool=new ArrayList<School>();
    listSchool.add(school);
    listSchool.add(school1);
    listSchool.add(school2);
    String str = JaxbMapper.toXml(listSchool,"schoolList",School.class);

    //写入到xml文件中
    String xmlPath = "D:/testConfig.xml";
    BufferedWriter bfw = new BufferedWriter(new FileWriter(new File(xmlPath)));
    bfw.write(str);
    bfw.close();
    }
    }


    下面是由listSchool转化成的xml文件,内容如下:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <schoolList>
    <list>
    <address>成都市武侯区天府五街</address>
    <level>高级中学</level>
    <name>华阳中学</name>
    <popular>5000</popular>
    <Student name="张三" number="10001" sex="男">
    <className>尖子班</className>
    <hobbys>
    <hobby>篮球</hobby>
    <hobby>音乐</hobby>
    <hobby>乒乓球</hobby>
    </hobbys>
    </Student>
    <Student name="李四" number="10002" sex="男">
    <className>普通班</className>
    <hobbys>
    <hobby>篮球</hobby>
    <hobby>音乐</hobby>
    <hobby>乒乓球</hobby>
    </hobbys>
    </Student>
    <Student name="莉莉" number="10003" sex="女">
    <className>普通班</className>
    <hobbys>
    <hobby>篮球</hobby>
    <hobby>音乐</hobby>
    <hobby>乒乓球</hobby>
    </hobbys>
    </Student>
    </list>
    <list>
    <address>成都市武侯区天府五街</address>
    <level>高级中学</level>
    <name>华阳中学</name>
    <popular>5000</popular>
    <Student name="张三" number="10001" sex="男">
    <className>尖子班</className>
    <hobbys>
    <hobby>篮球</hobby>
    <hobby>音乐</hobby>
    <hobby>乒乓球</hobby>
    </hobbys>
    </Student>
    <Student name="李四" number="10002" sex="男">
    <className>普通班</className>
    <hobbys>
    <hobby>篮球</hobby>
    <hobby>音乐</hobby>
    <hobby>乒乓球</hobby>
    </hobbys>
    </Student>
    <Student name="莉莉" number="10003" sex="女">
    <className>普通班</className>
    <hobbys>
    <hobby>篮球</hobby>
    <hobby>音乐</hobby>
    <hobby>乒乓球</hobby>
    </hobbys>
    </Student>
    </list>
    <list>
    <address>成都市武侯区天府五街</address>
    <level>高级中学</level>
    <name>华阳中学</name>
    <popular>5000</popular>
    <Student name="张三" number="10001" sex="男">
    <className>尖子班</className>
    <hobbys>
    <hobby>篮球</hobby>
    <hobby>音乐</hobby>
    <hobby>乒乓球</hobby>
    </hobbys>
    </Student>
    <Student name="李四" number="10002" sex="男">
    <className>普通班</className>
    <hobbys>
    <hobby>篮球</hobby>
    <hobby>音乐</hobby>
    <hobby>乒乓球</hobby>
    </hobbys>
    </Student>
    <Student name="莉莉" number="10003" sex="女">
    <className>普通班</className>
    <hobbys>
    <hobby>篮球</hobby>
    <hobby>音乐</hobby>
    <hobby>乒乓球</hobby>
    </hobbys>
    </Student>
    </list>
    </schoolList>


    ————————————————
    版权声明:本文为CSDN博主「mountainGS」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/u010331823/java/article/details/78258311

  • 相关阅读:
    练习
    PHP练习
    foreach使用
    IPTABLES
    dhcp snooping、ARP防护、
    锐捷无线加密
    SQL基础五(作业代码)
    TensorFlow 制作自己的TFRecord数据集
    Tensorflow原理通用
    Python中图像的缩放 resize()函数的应用
  • 原文地址:https://www.cnblogs.com/zhoading/p/12634435.html
Copyright © 2011-2022 走看看