java WebService接口開發注意點 java 利用Xstream生成和解析xml知識結構

java 利用Xstream生成和解析xml,知識結構: 
1.Xstream簡介; 
使用限制: JDK版本不能<1.5. 
雖然預處理註解是安全的,但自動偵查註解可能發生競爭條件.


特點: 
簡化的API; 
無映射文件; 
高性能,低內存佔用; 
整潔的XML; 
不需要修改對象;支持內部私有字段,不需要setter/getter方法,final字段;非公有類,內部類;類不需要默認構造器,完全對象圖支持.維護對象引用計數,循環引用. i 
提供序列化接口; 
自定義轉換類型策略; 
詳細的錯誤診斷; 
快速輸出格式;當前支持 JSON 和 morphing. 


使用場景 
Transport 轉換 
Persistence 持久化對象 
Configuration 配置 
Unit Tests 單元測


隱式集合 
當我們使用集合類時不想顯示集合,只顯示裏面的元素即可. 
使用隱式集合前: 
<list> 
 <element /> 
 <element /> 
<list> 


使用隱式集合: 
xstream.addImplicitCollection(Person.class, "list"); 


使用隱式集合後: 
 <element /> 
 <element /> 




 2.Xstream註解常用知識: 
@XStreamAlias("message") 別名註解  
作用目標: 類,字段  
@XStreamImplicit 隱式集合  
@XStreamImplicit(itemFieldName="part")  
作用目標: 集合字段  
@XStreamConverter(SingleValueCalendarConverter.class) 注入轉換器  
作用目標: 對象  
@XStreamAsAttribute 轉換成屬性  
作用目標: 字段  
@XStreamOmitField 忽略字段  
作用目標: 字段  
Auto-detect Annotations 自動偵查註解   
xstream.autodetectAnnotations(true);  
自動偵查註解與XStream.processAnnotations(Class[] cls)的區別在於性能.自動偵查註解將緩存所有類的類型.  
3.案例分析: (1)同一標籤下多個同名元素; 

                   (2)同一標籤下循環多個對象;


1. [代碼]1.實體類:PersonBean  

import java.util.List;
 
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
 
/**
 *@ClassName:PersonBean
 *@author: chenyoulong  Email: [email protected]
 *@date :2012-9-28 下午3:10:47
 *@Description:TODO 
 */
@XStreamAlias("person")
public class PersonBean {
    @XStreamAlias("firstName")
    private String firstName;
    @XStreamAlias("lastName")
    private String lastName;
     
    @XStreamAlias("telphone")
    private PhoneNumber tel;
    @XStreamAlias("faxphone")
    private PhoneNumber fax;
     
    //測試一個標籤下有多個同名標籤
    @XStreamAlias("friends")
    private Friends friend;
     
    //測試一個標籤下循環對象
    @XStreamAlias("pets")
    private Pets pet;
     
     
    //省略setter和getter
}

2. [代碼]2.實體類:PhoneNumber  

@XStreamAlias("phoneNumber")
    public  class PhoneNumber{
        @XStreamAlias("code")
        private int code;
        @XStreamAlias("number")
        private String number;
         
            //省略setter和getter
         
    }


3. [代碼]3.實體類:Friends(一個標籤下有多個同名標籤 )

/**
     * 用Xstream註解的方式實現:一個標籤下有多個同名標籤 
     *@ClassName:Friends
     *@author: chenyoulong  Email: [email protected]
     *@date :2012-9-28 下午4:32:24
     *@Description:TODO 5個name 中國,美國,俄羅斯,英國,法國
     *http://blog.csdn.net/menhuanxiyou/article/details/5426765
     */
    public static class Friends{
        @XStreamImplicit(itemFieldName="name")   //itemFieldName定義重複字段的名稱,
        /*<friends>                               <friends>
            <name>A1</name>                         <String>A1</String>
            <name>A2</name>    如果沒有,則會變成    =====>       <String>A1</String>
            <name>A3</name>                         <String>A1</String>
        </friends>                                </friends>
      */
        private List<String> name;
 
        public List<String> getName() {
            return name;
        }
 
        public void setName(List<String> name) {
            this.name = name;
        }
    }


4. [代碼]4.1實體類:Animal(同一標籤下循環對象實體1)   

//測試同一標籤下循環某一對象
    public  class Animal{
        @XStreamAlias("name")
        private String name;
        @XStreamAlias("age")
        private int age;
        public Animal(String name,int age){
            this.name=name;
            this.age=age;
        }
         
              //省略setter和getter
    }

5. [代碼]4.2實體類:Pets(同一標籤下循環對象實體2)    

**
     * 測試同一標籤下循環某一對象
     *@ClassName:Pets
     *@author: chenyoulong  Email: [email protected]
     *@date :2012-9-28 下午6:26:01
     *@Description:TODO
     */
    public class Pets{
        @XStreamImplicit(itemFieldName="pet")
        private List<Animal> animalList;
         
        public List<Animal> getAnimalList() {
            return animalList;
        }
 
        public void setAnimalList(List<Animal> animalList) {
            this.animalList = animalList;
        }
         
    }

6. [代碼]5.main函數示例1:toxml     

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JsonWriter.Format;
import com.thoughtworks.xstream.io.xml.DomDriver;
 
/**
 *@ClassName:PersonTest
 *@author: chenyoulong  
 *@date :2012-9-28 下午3:25:09
 *@Description:TODO 
 */
public class PersonTest {
 
    /** 
     * @Title: main 
     * @Description: TODO 
     * @param args 
     * @return void  
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
         
        PersonBean per=new PersonBean();
        per.setFirstName("chen");
        per.setLastName("youlong");
         
        PhoneNumber tel=new PhoneNumber();
        tel.setCode(137280);
        tel.setNumber("137280968");
         
        PhoneNumber fax=new PhoneNumber();
        fax.setCode(20);
        fax.setNumber("020221327");
        per.setTel(tel);
        per.setFax(fax);
         
         
        //測試一個標籤下有多個同名標籤
        List<String> friendList=new ArrayList<String>();
        friendList.add("A1");
        friendList.add("A2");
        friendList.add("A3");
        Friends friend1=new Friends();
        friend1.setName(friendList);
        per.setFriend(friend1);
         
        //測試一個標籤下循環對象
        Animal dog=new Animal("Dolly",2);
        Animal cat=new Animal("Ketty",2);
        List<Animal> petList=new ArrayList<Animal>();
        petList.add(dog);
        petList.add(cat);
        Pets pet=new Pets();
        pet.setAnimalList(petList);
        per.setPet(pet);
         
                    //java對象轉換成xml
        String xml=XmlUtil.toXml(per);
        System.out.println("xml==="+xml);
         
    }
}

7. [代碼]xml效果圖   
xml===<person>
  <firstName>chen</firstName>
  <lastName>youlong</lastName>
  <telphone>
    <code>137280</code>
    <number>137280968</number>
  </telphone>
  <faxphone>
    <code>20</code>
    <number>020221327</number>
  </faxphone>
  <friends>
    <name>A1</name>
    <name>A2</name>
    <name>A3</name>
  </friends>
  <pets>
    <pet>
      <name>doly</name>
      <age>2</age>
    </pet>
    <pet>
      <name>Ketty</name>
      <age>2</age>
    </pet>
  </pets>
</person>


8. [代碼]5.2 main函數示例2:toBean  

public static void main(String[] args) {
        // TODO Auto-generated method stub
         
        //toXml
//      String xmlStr=new PersonTest().toXml();
         
        //toBean
//      PersonBean per=new PersonTest().toBean();
        String xmlStr="<person>"+
                  "<firstName>chen</firstName>"+
                  "<lastName>youlong</lastName>"+
                  "<telphone>"+
                    "<code>137280</code>"+
                    "<number>137280968</number>"+
                  "</telphone>"+
                  "<faxphone>"+
                    "<code>20</code>"+
                    "<number>020221327</number>"+
                  "</faxphone>"+
                  "<friends>"+
                    "<name>A1</name>"+
                    "<name>A2</name>"+
                    "<name>A3</name>"+
                  "</friends>"+
                  "<pets>"+
                    "<pet>"+
                      "<name>doly</name>"+
                      "<age>2</age>"+
                    "</pet>"+
                    "<pet>"+
                      "<name>Ketty</name>"+
                      "<age>2</age>"+
                    "</pet>"+
                  "</pets>"+
                "</person>";
//用泛型的知識
        PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class);
        System.out.println("person=firstname=="+person.getFirstName());
        System.out.println("person==Friends==name1=="+person.getFriend().getName().get(0));
        System.out.println("person==Pets==name2=="+person.getPet().getAnimalList().get(1).getName());
 
/*
//效果與以下方法類同,(以下代碼較爲直觀)
XStream xstream=new XStream(new DomDriver()); //注意:不是new Xstream(); 否則報錯:
 
        xstream.processAnnotations(PersonBean.class);
        PersonBean person=(PersonBean)xstream.fromXML(xmlStr);
        System.out.println("person=firstname=="+person.getFirstName());
        System.out.println("person==Friends==name1=="+person.getFriend().getName().get(0));
        System.out.println("person==Pets==name=="+person.getPet().getAnimalList().get(1).getName());
*/
 
         
    }

9. [代碼]6.XmlUtil工具類(toxml()和toBean())   

/**
     * 輸出xml和解析xml的工具類
     *@ClassName:XmlUtil
     *@author: chenyoulong  Email: [email protected]
     *@date :2012-9-29 上午9:51:28
     *@Description:TODO
     */
    public class XmlUtil{
        /**
         * java 轉換成xml
         * @Title: toXml 
         * @Description: TODO 
         * @param obj 對象實例
         * @return String xml字符串
         */
        public static String toXml(Object obj){
            XStream xstream=new XStream();
//          XStream xstream=new XStream(new DomDriver()); //直接用jaxp dom來解釋
//          XStream xstream=new XStream(new DomDriver("utf-8")); //指定編碼解析器,直接用jaxp dom來解釋
             
            ////如果沒有這句,xml中的根元素會是<包.類名>;或者說:註解根本就沒生效,所以的元素名就是類的屬性
            xstream.processAnnotations(obj.getClass()); //通過註解方式的,一定要有這句話
            return xstream.toXML(obj);
        }
         
        /**
         *  將傳入xml文本轉換成Java對象
         * @Title: toBean 
         * @Description: TODO 
         * @param xmlStr
         * @param cls  xml對應的class類
         * @return T   xml對應的class類的實例對象
         * 
         * 調用的方法實例:PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class);
         */
        public static <T> T  toBean(String xmlStr,Class<T> cls){
            //注意:不是new Xstream(); 否則報錯:java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory
            XStream xstream=new XStream(new DomDriver());
            xstream.processAnnotations(cls);
            T obj=(T)xstream.fromXML(xmlStr);
            return obj;         
        } 
 
       /**
         * 寫到xml文件中去
         * @Title: writeXMLFile 
         * @Description: TODO 
         * @param obj 對象
         * @param absPath 絕對路徑
         * @param fileName  文件名
         * @return boolean
         */
       
        public static boolean toXMLFile(Object obj, String absPath, String fileName ){
            String strXml = toXml(obj);
            String filePath = absPath + fileName;
            File file = new File(filePath);
            if(!file.exists()){
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    log.error("創建{"+ filePath +"}文件失敗!!!" + Strings.getStackTrace(e));
                    return false ;
                }
            }// end if 
            OutputStream ous = null ;
            try {
                ous = new FileOutputStream(file);
                ous.write(strXml.getBytes());
                ous.flush();
            } catch (Exception e1) {
                log.error("寫{"+ filePath +"}文件失敗!!!" + Strings.getStackTrace(e1));
                return false;
            }finally{
                if(ous != null )
                    try {
                        ous.close();
                    } catch (IOException e) {
                        log.error("寫{"+ filePath +"}文件關閉輸出流異常!!!" + Strings.getStackTrace(e));
                    }
            }
            return true ;
        }
         
        /**
         * 從xml文件讀取報文
         * @Title: toBeanFromFile 
         * @Description: TODO 
         * @param absPath 絕對路徑
         * @param fileName 文件名
         * @param cls
         * @throws Exception 
         * @return T
         */
        public static <T> T  toBeanFromFile(String absPath, String fileName,Class<T> cls) throws Exception{
            String filePath = absPath +fileName;
            InputStream ins = null ;
            try {
                ins = new FileInputStream(new File(filePath ));
            } catch (Exception e) {
                throw new Exception("讀{"+ filePath +"}文件失敗!", e);
            }
             
            String encode = useEncode(cls);
            XStream xstream=new XStream(new DomDriver(encode));
            xstream.processAnnotations(cls);
            T obj =null;
            try {
                obj = (T)xstream.fromXML(ins);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                throw new Exception("解析{"+ filePath +"}文件失敗!",e);
            }
            if(ins != null)
                ins.close();
            return obj;         
        } 
         
    }

轉自:https://www.oschina.net/code/snippet_116183_14202
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章