1. 程式人生 > >java實體類和xml之間的轉換

java實體類和xml之間的轉換

一、XStream的用途

         XStream是一個Java物件和XML相互轉換的工具,很好很強大。提供了所有的基礎型別、陣列、集合等型別直接轉換的支援。 

         因此XML常用於資料交換、物件序列化(這種序列化和Java物件的序列化技術有著本質的區別)。

        Stream物件相當Java物件和XML之間的轉換器,轉換過程是雙向的。建立XSteam物件的方式很簡單,只需要new XStream()即

         可。
         Java到xml,用toXML()方法。
         Xml到Java,用fromXML()方法。

二、

       在沒有任何設定預設情況下,java到xml的對映,是java成員名對應xml的元素名,java類的全名對應xml根元素的名字。而實際中,往

      往是xml和java類都有了,要完成相互轉換,必須進行別名對映。

      別名配置包含三種情況:
      1、類別名,用alias(String name, Class type)。
      2、類成員別名,用aliasField(String alias, Class definedIn, String fieldName)
      3、類成員作為屬性別名,用 aliasAttribute(Class definedIn, String attributeName, String alias),單獨命名沒有意義,還要通過 

          useAttributeFor(Class definedIn, String fieldName) 應用到某個類上。
          別名的配置是非常重要的,但是其中有些細節問題很重要,在例子中會專門做詳細說明。

         另外還有不太常用的方法:
         addImplicitCollection(Class ownerType, String fieldName),去掉集合型別生成xml的父節點。
         registerConverter(Converter converter) ,註冊一個轉換器。

三、

如果這些基本的操作還不能滿足你應用的需求,XStream提供豐富的擴充套件點。你可以實現自己的轉換器。還可以利用XStream完成更負責的功能,比如輸出其他非xml格式的資料,還可以輸出html,還支援XML Dom型別資料,這些應用起來稍微複雜些。當然這些不是XStream應用的重點,也不用理會,真正需要的時候再檢視API和原始碼研究研究。

XStream的優點很多,但是也有一些小bug,比如在定義別名中的下劃線“_”轉換為xml後會變成“__”這個符號,很變態。因此,儘量避免在別名中實用任何符號,卻是需要下劃線的時候,可以考慮實用連線符“-”,這個沒有問題。

另外,我們的Java Bean中,常常有一些常量,在轉換過程,XStream也會將這些常量轉換過去,形成常量的xml節點,這顯然不是想要的結果,對於常量欄位,就不做轉換了。

四、

     簡單例子:

package test;

import java.util.List;

public class Person {
 private String name;
 private String age;
 private Profile profile;
 private List<Address> addlist;

 public Person(String name, String age, Profile profile,
   List<Address> addlist) {
  this.name = name;
  this.age = age;
  this.profile = profile;
  this.addlist = addlist;
 }
    public Person(){
     
    }
 public String toString() {
  return “Person{” + “name=’” + name + ‘\” + “, age=’” + age + ‘\”
    + “, profile=” + profile + “, addlist=” + addlist + ‘}’;
 }
}

//=======================================================

package test;

public class Address {
 private String add;
 private String zipcode;

 public Address(String add, String zipcode) {
  this.add = add;
  this.zipcode = zipcode;
 }

 public String toString() {
  return “Address{” + “add=’” + add + ‘\” + “, zipcode=’” + zipcode
    + ‘\” + ‘}’;
 }
}

//======================================================

package test;

public class Profile {
 private String job;
 private String tel;
 private String remark;

 public Profile(String job, String tel, String remark) {
  this.job = job;
  this.tel = tel;
  this.remark = remark;
 }

 public String toString() {
  return “Profile{” + “job=’” + job + ‘\” + “, tel=’” + tel + ‘\”
    + “, remark=’” + remark + ‘\” + ‘}’;
 }
}

//==========================================================

package test;

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.XStream;

public class XStreamTest {

 public static void main(String args[]) {
  test();
 }

 public static void test() {
  System.out
    .println(“———-XStream學習:http://lavasoft.blog.51cto.com———-“);
  // 目標物件
  Address address1 = new Address(“鄭州市經三路”, “450001”);
  Address address2 = new Address(“西安市雁塔路”, “710002”);
  List<Address> addList = new ArrayList<Address>();
  addList.add(address1);
  addList.add(address2);
  Profile profile = new Profile(“軟體工程師”, “13512129933”, “備註說明”);
  Person person = new Person(“熔岩”, “27”, profile, addList);

  // 轉換裝配
  XStream xStream = new XStream();
  output(0, xStream, person);
  /************** 設定類別名 ****************/
  xStream.alias(“PERSON”, test.Person.class);
  xStream.alias(“PROFILE”, test.Profile.class);
  xStream.alias(“ADDRESS”, test.Address.class);
  output(1, xStream, person);

  /************* 設定類成員的別名 ***************/
  // 設定Person類的name成員別名Name
  xStream.aliasField(“Name”, Person.class, “name”);
  /*
   * [注意] 設定Person類的profile成員別名PROFILE,這個別名和Profile類的別名一致,
   * 這樣可以保持XStream物件可以從profile成員生成的xml片段直接轉換為Profile成員,
   * 如果成員profile的別名和Profile的別名不一致,則profile成員生成的xml片段不可
   * 直接轉換為Profile物件,需要重新建立XStream物件,這豈不給自己找麻煩?
   */
  xStream.aliasField(“PROFILE”, test.Person.class, “profile”);
  xStream.aliasField(“ADDLIST”, test.Person.class, “addlist”);
  xStream.aliasField(“Add”, test.Address.class, “add”);
  xStream.aliasField(“Job”, test.Profile.class, “job”);
  output(2, xStream, person);

  /******* 設定類成員為xml一個元素上的屬性 *******/
  xStream.useAttributeFor(Address.class, “zipcode”);
  output(3, xStream, person);
  /************* 設定屬性的別名 ***************/
  xStream.aliasAttribute(Address.class, “zipcode”, “Zipcode”);
  output(4, xStream, person);
  /************* 將xml轉為java物件 ******× ****/
   String person_xml = “<PERSON>\n” + “  <Name>熔岩</Name>\n”
   + “  <age>27</age>\n” + “  <PROFILE>\n”
   + “    <Job>軟體工程師</Job>\n” + “    <tel>13512129933</tel>\n”
   + “    <remark>備註說明</remark>\n” + “  </PROFILE>\n”
   + “  <ADDLIST>\n” + “    <ADDRESS Zipcode=\”450001\”>\n”
   + “      <Add>鄭州市經三路</Add>\n” + “    </ADDRESS>\n”
   + “    <ADDRESS Zipcode=\”710002\”>\n”
   + “      <Add>西安市雁塔路</Add>\n” + “    </ADDRESS>\n”
   + “  </ADDLIST>\n” + “</PERSON>”;
   String profile_xml = “  <PROFILE>\n” + “    <Job>軟體工程師</Job>\n”
   + “    <tel>13512129933</tel>\n”
   + “    <remark>備註說明</remark>\n” + “  </PROFILE>”;
   String address_xml = “    <ADDRESS Zipcode=\”710002\”>\n”
   + “      <Add>西安市雁塔路</Add>\n” + “    </ADDRESS>”;
  
   // 同樣實用上面的XStream物件xStream
   System.out.println(xStream.fromXML(person_xml).toString());
   System.out.println(xStream.fromXML(profile_xml).toString());
   System.out.println(xStream.fromXML(address_xml).toString());
 }

 public static void output(int i, XStream xStream, Object obj) {
  String xml = xStream.toXML(obj);
  System.out.println(“>>>第[ ” + i + “]次輸出\n”);
  System.out.println(xml + “\n”);
 }
}

//=======================================================

———-XStream學習:http://lavasoft.blog.51cto.com———-
>>>第[ 0]次輸出

<test.Person>
  <name>熔岩</name>
  <age>27</age>
  <profile>
    <job>軟體工程師</job>
    <tel>13512129933</tel>
    <remark>備註說明</remark>
  </profile>
  <addlist>
    <test.Address>
      <add>鄭州市經三路</add>
      <zipcode>450001</zipcode>
    </test.Address>
    <test.Address>
      <add>西安市雁塔路</add>
      <zipcode>710002</zipcode>
    </test.Address>
  </addlist>
</test.Person>

>>>第[ 1]次輸出

<PERSON>
  <name>熔岩</name>
  <age>27</age>
  <profile>
    <job>軟體工程師</job>
    <tel>13512129933</tel>
    <remark>備註說明</remark>
  </profile>
  <addlist>
    <ADDRESS>
      <add>鄭州市經三路</add>
      <zipcode>450001</zipcode>
    </ADDRESS>
    <ADDRESS>
      <add>西安市雁塔路</add>
      <zipcode>710002</zipcode>
    </ADDRESS>
  </addlist>
</PERSON>

>>>第[ 2]次輸出

<PERSON>
  <Name>熔岩</Name>
  <age>27</age>
  <PROFILE>
    <Job>軟體工程師</Job>
    <tel>13512129933</tel>
    <remark>備註說明</remark>
  </PROFILE>
  <ADDLIST>
    <ADDRESS>
      <Add>鄭州市經三路</Add>
      <zipcode>450001</zipcode>
    </ADDRESS>
    <ADDRESS>
      <Add>西安市雁塔路</Add>
      <zipcode>710002</zipcode>
    </ADDRESS>
  </ADDLIST>
</PERSON>

>>>第[ 3]次輸出

<PERSON>
  <Name>熔岩</Name>
  <age>27</age>
  <PROFILE>
    <Job>軟體工程師</Job>
    <tel>13512129933</tel>
    <remark>備註說明</remark>
  </PROFILE>
  <ADDLIST>
    <ADDRESS zipcode=”450001”>
      <Add>鄭州市經三路</Add>
    </ADDRESS>
    <ADDRESS zipcode=”710002”>
      <Add>西安市雁塔路</Add>
    </ADDRESS>
  </ADDLIST>
</PERSON>

>>>第[ 4]次輸出

<PERSON>
  <Name>熔岩</Name>
  <age>27</age>
  <PROFILE>
    <Job>軟體工程師</Job>
    <tel>13512129933</tel>
    <remark>備註說明</remark>
  </PROFILE>
  <ADDLIST>
    <ADDRESS Zipcode=”450001”>
      <Add>鄭州市經三路</Add>
    </ADDRESS>
    <ADDRESS Zipcode=”710002”>
      <Add>西安市雁塔路</Add>
    </ADDRESS>
  </ADDLIST>
</PERSON>