zoukankan      html  css  js  c++  java
  • JAXB读写xml

    一、注解

    在Java模型中的创建与 xml 文件对应的节点和属性需要用注解来表示

    @XmlRootElement

    作用:将一个Java类映射为一段XML的根节点参数:
        name  定义这个根节点的名称
        namespace   定义这个根节点命名空间
    @XmlAccessorType  
    作用:定义映射这个类中的何种类型需要映射到XML。
    可接收四个参数,分别是:
        XmlAccessType.FIELD:表示将这个类中的 非静态(static)、非序列化(transient)属性映射到xml,有无get/set方法均可
        XmlAccessType.PROPERTY:使用 set/get 方法来序列化属性或者元素(get方法可不需注解自动映射)——说明:通过get方法映射到xml,get方法上是否添加注解都可,但是不能在属性上添加注解
        XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field(字段)或property(get/set对)同时映射到XML(默认注解),该注解包含了XmlAccessType.FIELD和XmlAccessType.PROPERTY两个注解,所以注意不要对同一个字段添加两次注解
        XmlAccessType.NONE:不映射
    补充说明:
        @XmlAccessorType的默认访问级别是 XmlAccessType.PUBLIC_MEMBER,因此,如果java对象中的private成员变量设置了public权限的 getter/setter方法,就不要在private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成 xml时会报同一个属性在java类里存在两次的错误。 
        同理,如果@XmlAccessorType的访问权限为XmlAccessType.NONE, 如果在java的成员变量上使用了@XmlElement或@XmlAttribute注解,这些成员变量依然可以映射到xml文件。
    @XmlElements
    // 表示或的关系,list集合中内容可以为以下两种类型
        @XmlElements({
            @XmlElement(name = "Person", type = Person.class),
            @XmlElement(name = "String", type = String.class)
        })
        private List list;
    补充说明:如果List使用泛型,则List集合中只能含有一种数据类型,此时使用该注解无用。
    @XmlElement  
    作用:指定一个字段或get/set方法映射到XML的节点。如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一个没有get/set方法的字段上标注此注解,即可将该字段映射到XML。
    参数:
        defaultValue        指定节点默认值
        name            指定节点名称
        namespace        指定节点命名空间
        type                定义该字段或属性的关联类型
        required            是否必须(默认为false)
        nillable            该字段是否包含 nillable="true" 属性(默认为false)
    @XmlAttribute
    作用:指定一个字段或get/set方法映射到XML的属性(区别@XmlElement——节点)。
    参数:
        Name            指定属性名称
        namespace        指定属性命名空间
        required         是否必须(默认为false)
    @XmlTransient  
    作用:定义某一字段或属性不需要被映射为XML。
    如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一get/set方法的字段上标注此注解,那么该属性则不会被映射。
    @XmlType  
    作用:定义映射的一些相关规则
    参数:
        propOrder        指定映射XML时的节点顺序
        factoryClass        指定UnMarshal时生成映射类实例所需的工厂类,默认为这个类本身
        factoryMethod    指定工厂类的工厂方法
        name            定义XML Schema中type的名称 
        namespace        指定Schema中的命名空间
    @XmlElementWrapper  
    作用:为数组元素或集合元素定义一个父节点。
    如,类中有一元素为List items,若不加此注解,该元素将被映射为
        <items>...</items>
        <items>...</items>
    这种形式,此注解可将这个元素进行包装,如:
        @XmlElementWrapper(name="items")
        @XmlElement(name="item")
        public List items;
    将会生成这样的XML样式:
        <items>
            <item>...</item>
            <item>...</item>
        </items>
    @XmlJavaTypeAdapter  
    作用:自定义某一字段或属性映射到XML的适配器。
    如,类中包含一个接口,我们可以定义一个适配器(继承自 javax.xml.bind.annotation.adapters.XmlAdapter类),指定这个接口如何映射到XML。
    @XmlSchema 
    作用:配置整个包的namespace,这个注解需放在package-info.java文件中

    二、代码实例

    /**  
     * @Title:  Menus.java   
     * @Package cn.com.kamfu.base   
     * @Description:    TODO(用一句话描述该文件做什么)   
     * @author: liandy    
     * @date:   2019年7月17日 上午1:41:42   
     * @version V1.0 
     */
    package cn.com.kamfu.lang;
    
    import java.util.List;
    
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlElementWrapper;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlSeeAlso;
    
    /**   
     * @ClassName:  Menus   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: liandy 
     * @date:   2019年7月17日 上午1:41:42   
     *     
     */
    @XmlRootElement(name = "items")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class ListObj<T> {
        @XmlElement(name = "item")
        private List<T> item;
    
        public List<T> getItem() {
            return item;
        }
    
        public void setItem(List<T> item) {
            this.item = item;
        }
        
    }
    ListObj
    /**  
     * @Title:  XmlList.java   
     * @Package cn.com.kamfu.base   
     * @Description:    TODO(用一句话描述该文件做什么)   
     * @author: liandy    
     * @date:   2019年7月17日 上午12:16:58   
     * @version V1.0 
     */
    package cn.com.kamfu.lang;
    
    import java.util.List;
    
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlElementWrapper;
    import javax.xml.bind.annotation.XmlRootElement;
    
    /**   
     * @ClassName:  XmlList   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: liandy 
     * @date:   2019年7月17日 上午12:16:58   
     *     
     */
    
    
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Menu {
        @XmlElement(name = "id")
        private String id;
        @XmlElement(name = "name")
        private String name;
        @XmlElement(name = "url")
        private String url;
        @XmlElementWrapper(name = "items")
        private List<Menu> item;
    
        
        
        public Menu() {
            super();
        }
    
        public Menu(String id, String name, String url) {
            super();
            this.id = id;
            this.name = name;
            this.url = url;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public List<Menu> getMenu() {
            return item;
        }
    
        public void setMenu(List<Menu> menu) {
            this.item = menu;
        }
    
        
    
    
    }
    Menu
    package cn.com.kamfu.util;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.enterprise.inject.New;
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    
    import org.dom4j.jaxb.JAXBReader;
    
    import cn.com.kamfu.lang.ListObj;
    import cn.com.kamfu.lang.Menu;
    
    public class JaxbXmlUtil {
    
        
        /**   
         * @Title: marshallerByJaxb   
         * @Description: TODO(这里用一句话描述这个方法的作用)   
         * @param: @param path
         * @param: @param object
         * @param: @param classesToBeBound      
         * @return: void      
         * @throws   
         */
        public static void marshallerByJaxb(String path,Object object,Class... classesToBeBound) {
            try {
                JAXBContext jc = JAXBContext.newInstance(classesToBeBound);
                    
                Marshaller marshaller = jc.createMarshaller();            
                marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");// 编码格式
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// 是否格式化生成的xml串
                marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);// 是否省略xml头声明信息
    
                File file = new File(path);
                if (!file.exists()) {
                    file.createNewFile();
                }
                marshaller.marshal(object, file);
            } catch (JAXBException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        
        public static Object unmarshallerByJaxb(String path,Object object,Class... classesToBeBound) {
            try {
                JAXBContext jc = JAXBContext.newInstance(classesToBeBound);
                    
                Unmarshaller unmarshaller = jc.createUnmarshaller();
                    
                File file = new File(path);
                if (!file.exists()) {
                    throw new FileNotFoundException("Can not load xml file!");
                }
                    
                return unmarshaller.unmarshal(file);
            } catch (JAXBException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
        public static void main(String[] args) throws JAXBException {
            ListObj<Menu> listObj=new ListObj<Menu>();
            List<Menu> menuallList=new ArrayList<Menu>();
            
            Menu menu = new Menu("1","用户管理","");
            Menu item1=new Menu("2","新增用户","");
            Menu item2=new Menu("2","删除用户","");
            Menu item3=new Menu("2","修改用户","");
            Menu item4=new Menu("2","查询用户","");
            
            List<Menu> list=new ArrayList<Menu>();
            list.add(item1);list.add(item2);list.add(item3);list.add(item4);
            menu.setMenu(list);
            menuallList.add(menu);menuallList.add(menu);menuallList.add(menu);
            listObj.setItem(menuallList);
            URL url=JAXBReader.class.getClassLoader().getResource("");
            String path=url.getFile().toString()+"config/menu.xml";
            JaxbXmlUtil.marshallerByJaxb(path,listObj, listObj.getClass(),menu.getClass());        
            ListObj<Menu> ssListObj=(ListObj<Menu>) JaxbXmlUtil.unmarshallerByJaxb(path,new ListObj<Menu>(),listObj.getClass(),menu.getClass());
            System.out.println(1);
        }
    }
    JaxbXmlUtil

    三、List、Map集合类型说明

    集合必须封装在对象内部才能使用jaxb转为xml,不能直接将集合直接转为xml
    3.1 List
    List集合或数组只要封装到对象内部,使用@XMLElementWrapper注解
    说明:当对象内部只有一个List集合的属性时,可以不加@XMLElementWrapper注解增加一层节点,直接将List结合内的对象作为根节点下的二级节点即可。
    3.2 Map
    如:Map<String, Person>集合,Person为自定义的一个对象
    1.创建一个新对象(如:AllPerson)作为中转对象,该对象内含有两个属性,分别是String和Person类型的(前者为Map的key,后者为Map的value);
    2.使用@XMLJavaTypeAdapter注解将Map<String, Person>转为AllPerson[],数组的大小与Map的大小相同;
    总结:XmlAdapter中的两个方法各有用处,注意不要漏掉
    Object->xml时
    Map<String, Person>—转为—> AllPerson[](AllPerson对象中包含String, Person)
    Xml->Object时
    AllPerson[](AllPerson对象中包含String, Person)—转为—> Map<String, Person>

  • 相关阅读:
    Restful levels &HATEOAS基本介绍~
    跨源资源共享(CORS)概念、实现(用Spring)、起源介绍
    Ubuntu下math库函数编译时未定义问题的解决
    常用软件清单~
    JetBrains PyCharm 专业版激活
    hello1.java内容简单介绍
    hello1 web项目中web.xml作用分析
    hello2 source analisis(notes)
    Servlet filter
    分析helo1项目中的 Web.xml
  • 原文地址:https://www.cnblogs.com/liandy001/p/11198558.html
Copyright © 2011-2022 走看看