Xmap与Jaxb

XMAP

Xmap使用dom解析xml,注册XValueFactory可以对特殊类型的节点增加自定义处理,但经调试serialize时context为空,如果想动态的往root节点中添加节点,非常困难,但经源码跟踪与调试,终于找到了解决办法。

总结:xmap不如jaxb灵活,扩展性差,序列化的时候还会自动生成root节点,这些都不是我们所需要的,只适合简单的匹配场合。

1. Library类

/**

 * 创建于:2016年2月29日 下午3:37:50

 * 所属项目:

 * 文件名称:Library.java

 * 作者:jiangchunyan

 * 版权信息:

 */

package xmap;

 

import java.util.ArrayList;

import java.util.List;

 

importorg.nuxeo.common.xmap.annotation.XNodeList;

import org.nuxeo.common.xmap.annotation.XObject;

@XObject(value="library")

public class Library {

        

         @XNodeList(value="book",type=ArrayList.class, componentType=Book.class)

         privateList<Book> books;

 

         publicList<Book> getBooks() {

                   returnbooks;

         }

 

         publicvoid setBooks(List<Book> books) {

                   this.books= books;

         }

        

}

 

2.Book类

/**

 * 创建于:2016年2月29日 下午3:38:11

 * 所属项目:

 * 文件名称:Book.java

 * 作者:jiangchunyan

 * 版权信息:

 */

package xmap;

 

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

 

import org.nuxeo.common.xmap.annotation.XContent;

importorg.nuxeo.common.xmap.annotation.XNode;

importorg.nuxeo.common.xmap.annotation.XNodeList;

importorg.nuxeo.common.xmap.annotation.XNodeMap;

importorg.nuxeo.common.xmap.annotation.XObject;

@XObject

public class Book {

         //book节点的属性no

         @XNode("@no")

         privateString no;

        

         //将属性绑定到给定的xml节点的内容

         @XContent("id")

         privateString id;

        

         //将属性绑定到一个新的xml节点

         @XNode(value="title")

         privateString title;

        

         //将属性绑定到一系列的xml节点

         @XNodeList(value="subject",type=String[].class, componentType=String.class)

         privateString[] subjects;

        

         @XNode(value="name/firstname")

         privateString firstname;

        

         @XNode(value="name/lastname")

         privateString lastname;

        

         //将map绑定到一系列xml节点

         @XNodeMap(componentType=String.class,key="@name", type=HashMap.class, value="address")

         privateMap<String, String> addressMap;

        

         @XNode("author")

         privateAuthor author;

        

         @XNode(value="publish")

         privateDate publishDate;

        

         publicString getTitle() {

                   returntitle;

         }

         publicvoid setTitle(String title) {

                   this.title= title;

         }

         publicString[] getSubjects() {

                   returnsubjects;

         }

         publicvoid setSubjects(String[] subjects) {

                   this.subjects= subjects;

         }

         publicString getFirstname() {

                   returnfirstname;

         }

         publicvoid setFirstname(String firstname) {

                   this.firstname= firstname;

         }

         publicString getLastname() {

                   returnlastname;

         }

         publicvoid setLastname(String lastname) {

                   this.lastname= lastname;

         }

         publicString getId() {

                   returnid;

         }

         publicvoid setId(String id) {

                   this.id= id;

         }

         publicMap<String, String> getAddressMap() {

                   returnaddressMap;

         }

         publicvoid setAddressMap(Map<String, String> addressMap) {

                   this.addressMap= addressMap;

         }

         publicAuthor getAuthor() {

                   returnauthor;

         }

         publicvoid setAuthor(Author author) {

                   this.author= author;

         }

         publicDate getPublishDate() {

                   returnpublishDate;

         }

         publicvoid setPublishDate(Date publishDate) {

                   this.publishDate= publishDate;

         }

         publicString getNo() {

                   returnno;

         }

         publicvoid setNo(String no) {

                   this.no= no;

         }

        

        

}

 

3. Author类

/**

 * 创建于:2016年3月4日 下午4:19:49

 * 所属项目:

 * 文件名称:Author.java

 * 作者:jiangchunyan

 * 版权信息:

 */

package xmap;

 

importorg.nuxeo.common.xmap.annotation.XNode;

importorg.nuxeo.common.xmap.annotation.XObject;

import org.nuxeo.common.xmap.annotation.XParent;

 

@XObject

public class Author {

         //Book对象是当前Author对象的父节点,暂未发现其作用?

         @XParent

         privateBook owner;

        

         @XNode("firstName")

         privateString firstName;

        

         @XNode("lastName")

         privateString lastName;

        

         publicString getFirstName() {

                   returnfirstName;

         }

 

         publicvoid setFirstName(String firstName) {

                   this.firstName= firstName;

         }

 

         publicString getLastName() {

                   returnlastName;

         }

 

         publicvoid setLastName(String lastName) {

                   this.lastName= lastName;

         }

 

         publicBook getOwner() {

                   returnowner;

         }

 

         publicvoid setOwner(Book owner) {

                   this.owner= owner;

         }

        

        

}

 

4. Test类

/**

 * 创建于:2016年3月1日 上午10:51:21

 * 所属项目:

 * 文件名称:Test.java

 * 作者:jiangchunyan

 * 版权信息:

 */

package xmap;

 

import java.io.InputStream;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

importorg.apache.http.client.utils.DateUtils;

import org.nuxeo.common.xmap.Context;

import org.nuxeo.common.xmap.XMap;

import org.nuxeo.common.xmap.XValueFactory;

 

public class Test {

         publicstatic void main(String[] args) throws Exception {

                   //xmlToBean();

                   beanToXml();

         }

        

         publicstatic void xmlToBean() throws Exception{

                   XMapxmap = new XMap();

                   xmap.setValueFactory(Date.class,new DateXValueFactory());

                   xmap.register(Library.class);

                   InputStreamin =Thread.currentThread().getContextClassLoader().getResourceAsStream("xmap/books.xml");

                   Librarylibrary = (Library)xmap.load(in);

                   List<Book>books = library.getBooks();

                   System.out.println(books);

         }

        

         publicstatic void beanToXml() throws Exception{

                   Bookbook = new Book();

                   book.setNo("abc");

                   book.setId("id1");

                   book.setSubjects(newString[]{"1", "2"});

                   book.setTitle("book1");

                   book.setFirstname("firstname");

                   book.setLastname("lastname");

                   book.setPublishDate(newDate());

 

                   Map<String,String> addressMap = new HashMap<String, String>();

                   addressMap.put("a1","aa1");

                   addressMap.put("a2","aa2");

                   book.setAddressMap(addressMap);

                  

                   Authorauthor = new Author();

                   author.setFirstName("13233333333");

                   author.setLastName("作者");

                   book.setAuthor(author);

                  

                   List<Book>books = new ArrayList<Book>();

                   books.add(book);

                  

                  

                   Librarylibrary = new Library();

                   library.setBooks(books);

                  

                   XMapxmap = new XMap();

                   xmap.setValueFactory(Date.class,new DateXValueFactory());

                   xmap.register(Library.class);

                   Stringxml = xmap.toXML(library);

                   System.out.println(xml);

         }

        

         privatestatic class DateXValueFactory extends XValueFactory{

                   @Override

                   publicString serialize(Context context, Object value) {

                            returnDateUtils.formatDate((Date)value, "yyyy-MM-dd HH:mm:ss");

                   }

                  

                   @Override

                   publicObject deserialize(Context context, String value) {

                           

                            returnDateUtils.parseDate(value, new String[]{"yyyy-MM-dd HH:mm:ss"});

                   }

         }

}

 

5.books.xml

<?xml version="1.0"encoding="UTF-8"?>

<root>

   <library>

        <book no="abc">

            <id>id1</id>

            <title>book1</title>

            <subject>1</subject>

            <subject>2</subject>

            <name>

                <firstname>firstname</firstname>

                <lastname>lastname</lastname>

            </name>

            <address name="a1">aa1</address>

            <address name="a2">aa2</address>

            <author>

                <firstName>13233333333</firstName>

                <lastName>作者</lastName>

            </author>

            <publish>2016-03-04 09:18:16</publish>

        </book>

   </library>

</root>

 

6.序列化时动态增加节点

通过XValueFactory的序列化方法,动态增加节点

/**

 * 创建于:201637下午2:47:03

 * 所属项目:

 * 文件名称:Res.java

 * 作者:jiangchunyan

 * 版权信息:

 */

package xmap;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

 

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

 

import org.nuxeo.common.xmap.Context;

import org.nuxeo.common.xmap.DOMSerializer;

import org.nuxeo.common.xmap.XMap;

import org.nuxeo.common.xmap.XValueFactory;

import org.nuxeo.common.xmap.annotation.XNodeList;

import org.nuxeo.common.xmap.annotation.XObject;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.NodeList;

 

@XObject("AP")

public class Res {

 

    @XNodeList(type= List.class, value = "RESULTS/RESULT", componentType = Map.class)

    privateList<Map<String, String>> list;

 

    publicList<Map<String, String>> getList() {

        return list;

    }

 

    public voidsetList(List<Map<String, String>> list) {

        this.list =list;

    }

 

    private staticclass MapXValueFactory extends XValueFactory {

        privateElement root;

        Documentdoc;

 

        publicMapXValueFactory(Element root, Document doc) {

            this.root= root;

            this.doc= doc;

        }

 

        @Override

        publicObject deserialize(Context context, String value) {

 

            returnnull;

        }

 

        @Override

        publicString serialize(Context context, Object value) {

            Elementresults = null;

            NodeListnodeList = root.getElementsByTagName("RESULTS");

            if(nodeList.getLength() == 0) {

                results= doc.createElement("RESULTS");

            } else {

                results= (Element) nodeList.item(0);

            }

 

            Elementresult = doc.createElement("RESULT");

 

            Map<String,String> map = (Map<String, String>) value;

            Iterator<Entry<String,String>> itera = map.entrySet().iterator();

            while(itera.hasNext()) {

                Entry<String,String> entry = itera.next();

                Stringkey = entry.getKey();

                Stringval = entry.getValue();

                if(key == null || key.equals("")) {

                    continue;

                }

                if(val == null) {

                    val= "";

                }

               

                Elementele = doc.createElement(key);

                ele.setTextContent(val);

 

                result.appendChild(ele);

            }

 

            results.appendChild(result);

            doc.getElementsByTagName("root").item(0).getFirstChild()

                    .appendChild(results);

 

            returnnull;

        }

    }

 

    public staticvoid main(String[] args) throws Exception {

        Res res =new Res();

        List<Map<String,String>> list = new ArrayList<Map<String, String>>();

        Map<String,String> map = new HashMap<String, String>();

        map.put("id","lalalla");

        map.put("name","test");

        list.add(map);

        Map<String,String> map1 = new HashMap<String, String>();

        map1.put("id","lalalla2");

        map1.put("name","test2");

        list.add(map1);

        res.setList(list);

 

        DocumentBuilderFactorydbfac = DocumentBuilderFactory.newInstance();

        DocumentBuilderdocBuilder = dbfac.newDocumentBuilder();

        Document doc= docBuilder.newDocument();

        Element root= doc.createElement("root");

        doc.appendChild(root);

 

        XMap xmap =new XMap();

        xmap.setValueFactory(Map.class,new MapXValueFactory(root, doc));

        xmap.register(Res.class);

 

        xmap.toXML(res,root);

 

        String xml =DOMSerializer.toString(root);

        System.out.println(xml);

    }

 

}

 

打印结果:

<?xml version="1.0"encoding="UTF-8"?>

<root>

   <AP>

        <RESULTS>

            <RESULT>

                <name>test</name>

                <id>lalalla</id>

            </RESULT>

            <RESULT>

                <name>test2</name>

                <id>lalalla2</id>

            </RESULT>

        </RESULTS>

   </AP>

</root>

 

JAXB

JDK中JAXB相关的重要Class和Interface:

 1、JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。

 2、Marshaller接口,将Java对象序列化为XML数据。

 3、Unmarshaller接口,将XML数据反序列化为Java对象。

Marshaller使用

JAXBContext jaxbContext = JAXBContext.newInstance(Library.class);

      Marshallermarshaller= jaxbContext.createMarshaller();

      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);

      marshaller.setProperty(Marshaller.JAXB_ENCODING,"GBK");

      marshaller.marshal(library, System.out);

JAXB常用注解

1.@XmlRootElement

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

2.@XmlElement


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

3.@XmlAttribute


@XmlAttribute用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。如:
@XmlAttribute(name="Country")
privateString state;

4.@XmlAccessorType

@XmlAccessorType用于指定由java对象生成xml文件时对java对象属性的访问方式。常与@XmlRootElement@XmlType一起使用。它的属性值是XmlAccessType4个枚举值,分别为:

·        XmlAccessType.FIELD:java对象中的所有成员变量

·        XmlAccessType.PROPERTYjava对象中所有通过getter/setter方式访问的成员变量

·        XmlAccessType.PUBLIC_MEMBERjava对象中所有的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文件。

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

 

5.@XmlAccessorOrder


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

6.@XmlTransient


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

 

7. @XmlType

 

@XmlType用在class类的注解,常与@XmlRootElement@XmlAccessorType一起使用。它有三个属性:namepropOrdernamespacefactoryClass、factoryMethod,经常使用的只有前两个属性。如:
同时使用了@XmlTypepropOrder={}

@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)的时候,生成的xml只按照propOrder定义的顺序生成元素@XmlType(name= "basicStruct", propOrder = {
    "intValue",
    "stringArray",
    "stringValue"
)
在使用@XmlTypepropOrder属性时,必须列出JavaBean对象中的所有属性,否则会报错。

factoryClass属性,指定UnMarshal时生成映射类实例所需的工厂类,默认为这个类本身。

factoryMethod属性,指定工厂类的工厂方法。

Name属性,定义XML Schematype的名称。

Namespace属性,指定Schema中的命名空间。

8. @XmlElementWrapper

为数组元素或集合元素定义一个父节点。如,类中有一元素为List items,若不加此注解,该元素将被映射为

<items>...</items>
<items>...</items>

这种形式,此注解可将这个元素进行包装,如:
   @XmlElementWrapper(name="items")

   @XmlElement(name="item")
    public List items;
将会生成这样的XML样式:
    <items>

       <item>...</item>
       <item>...</item>
    </items>

9. @XmlList 

这个等于是在同一行中,list中的输出,以空格形式分隔开来

   @XmlList

 

  private String[] subjects;

 

输出:

<subjects>sub1sub2</subjects>

10. @XmlList和@XmlAttribute混合使用 

@XmlList

   @XmlAttribute

  private String[] subjects;

输出:

<bookno="no" subjects="sub1 sub2">

12. @XmlList 和@XmlValue混用 

@XmlList 
    @XmlValue 

    private List<String>emailAddresses;

就是把emailAddresslist的值,作为<customer>value  输出,结果如下
<customer>janed@example.com
jdoe@example.org</customer>

13. @XmlJavaTypeAdapter

@XmlJavaTypeAdapter常用在转换比较复杂的对象时,如map类型或者格式化日期等。使用此注解时,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法。

日期格式化:

@XmlElement(name="publish")

   @XmlJavaTypeAdapter(DateXmlAdapter.class)

  private Date publishDate;

 

public classDateXmlAdapterextendsXmlAdapter<String, Date>{

 

   @Override

   public Date unmarshal(String v) throws Exception {

      if(v != null){

         SimpleDateFormatsdf= newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");

         return sdf.parse(v);

      }

      return null;

   }

 

   @Override

   public String marshal(Date v) throws Exception {

      if(v != null){

         SimpleDateFormatsdf= newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");

         return sdf.format(v);

      }

      return null;

   }

 

}

 

Map对象映射:

// map绑定到一系列xml节点

   @XmlJavaTypeAdapter(HashMapXmlAdapter.class)

  private Map<String, String> addressMap;

 

public classHashMapXmlAdapterextendsXmlAdapter<HashMapXmlAdapter.AdaptedMap,Map<String, String>>{

 

   @Override

   public Map<String,String> unmarshal(AdaptedMap adaptedMap) throwsException {

     

      return null;

   }

 

   /**

    * jaxb不认识的Map转成jaxb认识的类型

    */

   @Override

   public AdaptedMapmarshal(Map<String, String> map) throwsException {

      AdaptedMapadaptedMap= newAdaptedMap();

      

      ArrayList<MapEntry>list= newArrayList<MapEntry>();

     

     

        Iterator<java.util.Map.Entry<String,String>> itera= map.entrySet().iterator();

        while (itera.hasNext()) {

          MapEntrymapEntry= newMapEntry();

         

            java.util.Map.Entry<String,String> entry= itera.next();

            String key = entry.getKey();

            String value = entry.getValue();

            if (key == null|| key.equals("")) {

                continue;

            }

            if (value == null){

                value = "";

            }

          

            mapEntry.setKey(key);

            mapEntry.setValue(value);

            list.add(mapEntry);

        }

       

        adaptedMap.setEntry(list);

        return adaptedMap;

   }

  

   public static class AdaptedMap {

      private List<MapEntry> entry = newArrayList<MapEntry>();

 

      public List<MapEntry>getEntry() {

         return entry;

      }

 

      public voidsetEntry(List<MapEntry> entry) {

         this.entry = entry;

      }

   }

  

   public static class MapEntry {

        private String key;

        private String value;

     

        public String getKey() {

         return key;

      }

      public void setKey(String key) {

         this.key = key;

      }

      public String getValue() {

         return value;

      }

      public void setValue(String value) {

         this.value = value;

      }

  

   }

}

14. @XmlEnum和@XmlEnumValue

@XmlEnum(int.class)

public enumOpenFlag {

   @XmlEnumValue("0") CLOSE(0), @XmlEnumValue("1") OPEN(1);

  

   private int value;

   private OpenFlag(int value){

      this.value = value;

   }

   public int getValue() {

      return value;

   }

  

}

@XmlElement

  private OpenFlag openFlag;

结果:

<openFlag>0</openFlag>

15. @XmlElements

映射到元素列表

@XmlElements({

      @XmlElement(name="A", type=Integer.class),

      @XmlElement(name="B", type=Double.class)

   })

  private List priceList;

结果:

<A>10</A>

        <B>5.23</B>

根据类型使用适配器更改元素名称

@XmlJavaTypeAdapter(AuthorToPXmlAdapter.class)

   @XmlElements({

      @XmlElement(name="PA", type=PX.class),

      @XmlElement(name="PB", type=PY.class)

   })

  private Author author;

 

@XmlType(name="P")

public abstractclassP {

}

@XmlType(name="PX")

public classPX extendsP{

}

@XmlType(name="PY")

public classPY extendsP{

}

public classAuthorToPXmlAdapter extends XmlAdapter<P, Author>{

 

   @Override

   public Author unmarshal(P v) throws Exception {

      // TODO Auto-generated method stub

      return null;

   }

 

   @Override

   public P marshal(Author v) throws Exception {

      if("1".equals(v.getAge())){

         return new PX();

      }else{

         return new PY();

      }

   }

}

结果:

<PA/>

 

 

 

 

 

16. @XmlSeeAlso

告诉JAXB,在绑定这个类的时候也需要绑定其他的类。在Java中,我们不能根据指定的类列出继承了这个类的所有子类。通过@XmlSeeAlso,可以解决此类问题,告诉JaxbContext需要绑定哪些类。例如:有如下类,

 class Animal {}
 class Dog extends Animal {}
 class Cat extends Animal {}
 如果不是用@XmlSeeAlso注解,我们需要这样定义JaxbContext:

JAXBContext.newInstance(Dog.class,Cat.class) (Animal will be automatically picked up since Dog and Cat refers toit.)

如果使用XmlSeeAlso注解,你可以使用如下方式:

 @XmlSeeAlso({Dog.class,Cat.class})
 class Animal {}
 class Dog extends Animal {}
 class Cat extends Animal {}
 JAXBContext.newInstance(Animal.class). 
通过XmlSeeAlso注解,JAXB就可以正确的绑定DogCat类. 

 

17. @XmlElementRef

@XmlElementRef注解将JavaBean属性映射到由属性类型决定的Xml元素。

这个注释动态地将XML元素名称与JavaBean属性关联起来。当使用XmlElement注释JavaBean属性时,XML元素名称静态地派生自JavaBean属性名。然而,当使用此注释时,XML元素名称来自于运行时JavaBean属性的类型实例

例如:

@XmlRootElement(name="target")

    class Target {

        // The presence of @XmlElementRef indicates that the XML

        // element name will be derived from the @XmlRootElement

        // annotation on the type (for e.g. "jar" for JarTask).

        @XmlElementRef

        List<Task> tasks;

    }

 

    abstract class Task {

    }

 

    @XmlRootElement(name="jar")

    class JarTask extends Task {

        ...

    }

 

    @XmlRootElement(name="javac")

    class JavacTask extends Task {

        ...

    }

测试方法:

     Targettarget = new Target();

    target.tasks.add(new JarTask());

    target.tasks.add(new JavacTask());

    marshal(target);

 

输出的XML如下:

<target>

   <jar></jar>

   <javac></javac>

</target>

18. List<Map<String, String> 的序列化和反序列化

public class DataXmlAdapter extends XmlAdapter<Object, List<Map<String,String>>> {

 

    /**

     * 序列化方法。

     *

     * 把java bean转换成Element,方便JAXB按照指定格式序列化。

     */

    @Override

    public Object marshal(List<Map<String, String>>rows) throws Exception{

        // TODOAuto-generated method stub

        DocumentBuilderbuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

        Documentdocument = builder.newDocument();

        ElementrootEle = document.createElement("rows");

         

        for(Map<String,String> row:rows){

            ElementrowEle = document.createElement("row");

             

            Iterator<Entry<String,String>> itera = row.entrySet().iterator();

            while (itera.hasNext()) {

                Entry<String,String> entry = itera.next();

                Stringkey = entry.getKey();

                Stringvalue = entry.getValue();

                if (key == null ||key.equals("")) {

                    continue;

                }

                if (value == null) {

                    value= "";

                }

                ElementdetailEle = document.createElement(key);

                detailEle.setTextContent(value);

                rowEle.appendChild(detailEle);

            }

            rootEle.appendChild(rowEle);

        }

        document.appendChild(rootEle);

        return rootEle;

    }

 

    /**

     * 反序列化方法。

     *

     * 把Element转换成java bean。

     */

    @Override

    public List<Map<String, String>> unmarshal(Objectdatas) throws Exception{

        // TODO Auto-generatedmethod stub

        if(datas==null){

            return null;

        }

        NodeListrowlist = ((Element)datas).getChildNodes();

        if(rowlist== null){

            return null;

        }

        int rowCount = rowlist.getLength();

        if(rowCount== 0){

            return null;

        }

         

        List<Map<String,String>> result = new ArrayList<Map<String,String>>();

        for(int i = 0; i<rowCount; i++){

            NoderowNode = rowlist.item(i);

            if(!"detail".equals(rowNode.getNodeName())){

                continue;

            }

             

            NodeListdetailList = rowNode.getChildNodes();

            if(detailList== null){

                continue;

            }

            int detailCount = detailList.getLength();

            if(detailCount== 0){

                continue;

            }

             

            Map<String,String> detailMap = new HashMap<String,String>();

            for(int j = 0; j < detailCount; j++){

                NodedetailNode = detailList.item(j);

                Stringkey = detailNode.getNodeName();

                Stringvalue = detailNode.getTextContent();

                if(key== null ||"".equals(key)){

                    continue;

                }

                detailMap.put(key,value);

            }

            result.add(detailMap);

        }

        return result;

    }

 

}

JAXB 存在继承关系的序列化和反序列化

1.      类图如下:

2. Req

@XmlRootElement(name = "FPS")

@XmlAccessorType(XmlAccessType.FIELD)

public classReq {

   @XmlElement(name = "Version")

   private String version; // 报文版本

 

   @XmlElement(name = "TxType")

   private String txType; // 交易类型

  

   @XmlElement(name = "Sign")

   private String sign; // RSA签名

  

   @XmlElementRef

   private TxInfo txInfo;

}

3. TxInfo

@XmlRootElement(name="TxInfo")

@XmlAccessorType(XmlAccessType.FIELD)

@XmlSeeAlso(value={BalanceQryTxInfo.class,RechargeTxInfo.class})

public classTxInfo {

   @XmlElement(name = "FSINo")

   private String fsiNo; // 基金销售机构代码

  

   @XmlElement(name = "TxTime")

   private String txTime; // 交易发生时间

  

   @XmlElement(name = "TxOrderNo")

   private String txOrderNo; // 基金销售机构订单流水号

 

   @XmlElement(name = "TxTraceNo")

   private String txTraceNo; // 基金销售机构交易流水号

}

4. RechargeTxInfo

@XmlRootElement(name="TxInfo")

@XmlAccessorType(XmlAccessType.FIELD)

public classRechargeTxInfo extends TxInfo{

   @XmlElement(name = "FuiouUserId")

   private String fuiouUserId; // 客户富友用户Id

  

   @XmlElement(name= "ExtendInfo")

   private String extendInfo;//扩展域

  

   @XmlElement(name= "amount")

   private String amount;

}

5. BalanceQryTxInfo

@XmlRootElement(name="TxInfo")

@XmlAccessorType(XmlAccessType.FIELD)

public classBalanceQryTxInfo extends TxInfo{

   @XmlElement(name = "FuiouUserId")

   private String fuiouUserId; // 客户富友用户Id

  

   @XmlElement(name= "ChannelCd")

   private String channelCd;// 渠道号

  

   @XmlElement(name= "ExtendInfo")

   private String extendInfo;//扩展域

}

6.  Test

public classTest {

  

   public static void main(String[] args) throws Exception {

      BalanceQryTxInfotxInfo= newBalanceQryTxInfo();

      txInfo.setChannelCd("1002");

      txInfo.setFsiNo("2000000003");

      txInfo.setFuiouUserId("F0000001");

      txInfo.setTxOrderNo("1");

     

      Reqreq= newReq();

      req.setVersion("0.1");

      req.setTxType("query");

      req.setSign("lllllll");

      req.setTxInfo(txInfo);

     

      // 序列化

      JAXBContextcontext= JAXBContext.newInstance(Req.class);

      Marshallermarshaller= context.createMarshaller();

      StringWritersw = new StringWriter();

      marshaller.marshal(req, sw);

      Stringxml= sw.toString();

      System.out.println(xml);

     

      // 反序列化

      StringReaderin = new StringReader(xml);

      JAXBContextcontext2= JAXBContext.newInstance(Req.class, RechargeTxInfo.class);

      Unmarshallerunmarshaller= context2.createUnmarshaller();

      Reqres= (Req) unmarshaller.unmarshal(in);

      System.out.println(res.getTxInfo().getClass());

      System.out.println(JSON.toJSONString(res));

  }

7. 执行结果如下:

<?xml version="1.0"encoding="UTF-8"standalone="yes"?><FPS><Version>0.1</Version><TxType>query</TxType><Sign>lllllll</Sign><TxInfo><FSINo>2000000003</FSINo><TxOrderNo>1</TxOrderNo><FuiouUserId>F0000001</FuiouUserId><ChannelCd>1002</ChannelCd></TxInfo></FPS>

class xml.RechargeTxInfo

{"sign":"lllllll","txInfo":{"fsiNo":"2000000003","fuiouUserId":"F0000001","txOrderNo":"1"},"txType":"query","version":"0.1"}

注意:

@XmlElementRef

This annotationdynamically associates an XML element name with the JavaBean property. When aJavaBean property is annotated with XmlElement, the XMLelement name is statically derived from the JavaBean property name. However,when this annotation is used, the XML element name is derived from the instanceof the type of the JavaBean property at runtime.

大意是指使用了@XmlElementRef后,xml元素的名称来自运行时中实例的类型。

如果我们不加此注解,那么序列化后的xml串如下:<?xmlversion="1.0" encoding="UTF-8"standalone="yes"?><FPS><Version>0.1</Version><TxType>query</TxType><Sign>lllllll</Sign><txInfoxsi:type="balanceQryTxInfo"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><FSINo>2000000003</FSINo><TxOrderNo>1</TxOrderNo><FuiouUserId>F0000001</FuiouUserId><ChannelCd>1002</ChannelCd></txInfo></FPS>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值