<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Knight of the round table

    wansong

    XStream Annotations 入門【翻譯】

    1、簡(jiǎn)單的轉(zhuǎn)換器:

    首先創(chuàng)建示例的環(huán)境,
    下面介紹的是最基礎(chǔ)的轉(zhuǎn)換器,首先創(chuàng)建一個(gè)Person類:

    package com.thoughtworks.xstream.examples;
    public class Person {
    private String name;
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    }

     接著,我們創(chuàng)建一個(gè)實(shí)例,并轉(zhuǎn)化他:

    package com.thoughtworks.xstream.examples;
    import com.thoughtworks.xstream.XStream;
    import com.thoughtworks.xstream.io.xml.DomDriver;
    public class PersonTest {
    public static void main(String[] args) {
    Person person = new Person();
    person.setName("Guilherme");
    XStream xStream = new XStream(new DomDriver());
    System.out.println(xStream.toXML(person));
    }
    }

     如你所料,得到下面的結(jié)果:

    <com.thoughtworks.xstream.examples.Person>
    <name>Guilherme</name>
    </com.thoughtworks.xstream.examples.Person>

    下面我們?yōu)閜erson類創(chuàng)建一個(gè)別名:

    XStream xStream = new XStream(new DomDriver());
    xStream.alias("person", Person.class);
    System.out.println(xStream.toXML(person));

    現(xiàn)在的結(jié)果就很易讀了:

    <person>
    <name>Guilherme</name>
    </person>

    到此,我們已經(jīng)建立好一個(gè)可以供我們實(shí)驗(yàn)的基礎(chǔ)例子了,下面我們來(lái)看看XStream的轉(zhuǎn)換器能為我們做些什么:
    2,創(chuàng)建一個(gè)Person轉(zhuǎn)換器:
    下面我們來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的轉(zhuǎn)換器,它能:
    1,用來(lái)轉(zhuǎn)換Person類
    2,將Person實(shí)例轉(zhuǎn)換成XML
    3,將xml轉(zhuǎn)換為Person實(shí)例
    首先創(chuàng)建一個(gè)PersonConverter類,并讓這個(gè)類實(shí)現(xiàn)Converter接口:

    package com.thoughtworks.xstream.examples;
    import com.thoughtworks.xstream.converters.Converter;
    import com.thoughtworks.xstream.converters.MarshallingContext;
    import com.thoughtworks.xstream.converters.UnmarshallingContext;
    import com.thoughtworks.xstream.io.HierarchicalStreamReader;
    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
    public class PersonConverter implements Converter {
    public boolean canConvert(Class clazz) {
    return false;
    }
    public void marshal(Object value, HierarchicalStreamWriter writer,
    MarshallingContext context) {
    }
    public Object unmarshal(HierarchicalStreamReader reader,
    UnmarshallingContext context) {
    return null;
    }
    }

    下面,我們首先告訴轉(zhuǎn)換器,我們只能轉(zhuǎn)換Person類,而不是別的類,包括其子類:

    public boolean canConvert(Class clazz) {
    return clazz.equals(Person.class);
    }

    這一步很簡(jiǎn)單,除非你是用來(lái)處理泛型的轉(zhuǎn)換器是會(huì)困難一點(diǎn)。

    Marshal方法是用來(lái)將對(duì)象轉(zhuǎn)換為XML的,他有三個(gè)參數(shù):
    1,我們準(zhǔn)備轉(zhuǎn)換的對(duì)象
    2,我們準(zhǔn)備輸出對(duì)象的writer
    3,當(dāng)前的marshaling context
    首先我們將object轉(zhuǎn)換成Person

    Person person = (Person) value;
    接著,我們就可以開始輸出數(shù)據(jù)了,首先我們創(chuàng)建一個(gè)叫做fullname的節(jié)點(diǎn),并將person的名字傳給他:

    writer.startNode("fullname");
    writer.setValue(person.getName());
    writer.endNode();

    呵呵~很簡(jiǎn)單吧,

    public void marshal(Object value, HierarchicalStreamWriter writer,
    MarshallingContext context) {
    Person person = (Person) value;
    writer.startNode("fullname");
    writer.setValue(person.getName());
    writer.endNode();
    }

    我們可以任意次數(shù)的調(diào)用start/end node方法,但需要記住,你必須在打開一個(gè)節(jié)點(diǎn)之后記住關(guān)閉它。一般來(lái)說(shuō),執(zhí)行轉(zhuǎn)換的操作在setValue方法調(diào)用時(shí)發(fā)生。
    下面,我們進(jìn)入unmarshal方法,我們使用moveDown和moveUp方法在節(jié)點(diǎn)樹層次中移動(dòng),所以,這里我們只需要簡(jiǎn)單的moveDown,得到值,再moveUp:

    Person person = new Person();
    reader.moveDown();
    person.setName(reader.getValue());
    reader.moveUp();

    最后,我們得到了一個(gè)這樣的轉(zhuǎn)換器:

    package com.thoughtworks.xstream.examples;
    import com.thoughtworks.xstream.converters.Converter;
    import com.thoughtworks.xstream.converters.MarshallingContext;
    import com.thoughtworks.xstream.converters.UnmarshallingContext;
    import com.thoughtworks.xstream.io.HierarchicalStreamReader;
    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
    public class PersonConverter implements Converter {
    public boolean canConvert(Class clazz) {
    return clazz.equals(Person.class);
    }
    public void marshal(Object value, HierarchicalStreamWriter writer,
    MarshallingContext context) {
    Person person = (Person) value;
    writer.startNode("fullname");
    writer.setValue(person.getName());
    writer.endNode();
    }
    public Object unmarshal(HierarchicalStreamReader reader,
    UnmarshallingContext context) {
    Person person = new Person();
    reader.moveDown();
    person.setName(reader.getValue());
    reader.moveUp();
    return person;
    }
    }

    接著,我們?cè)谖覀兊膍ain方法中注冊(cè)這個(gè)轉(zhuǎn)化器:

    package com.thoughtworks.xstream.examples;
    import com.thoughtworks.xstream.XStream;
    import com.thoughtworks.xstream.io.xml.DomDriver;
    public class PersonTest {
    public static void main(String[] args) {
    Person person = new Person();
    person.setName("Guilherme");
    XStream xStream = new XStream(new DomDriver());
    xStream.registerConverter(new PersonConverter());
    xStream.alias("person", Person.class);
    System.out.println(xStream.toXML(person));
    }
    }

    注意到我們?cè)趺醋?cè)我們的轉(zhuǎn)換器了么?只需要下面簡(jiǎn)單的一句:

    xStream.registerConverter(new PersonConverter());
    最終得到的結(jié)果是:

    <person>
      <fullname>Guilherme</fullname>
    </person>
    也許你會(huì)說(shuō):這只改變了我輸出的樹,我需要用它來(lái)轉(zhuǎn)換數(shù)據(jù)。
    下面我們來(lái)嘗試在person標(biāo)簽中創(chuàng)建一個(gè)叫做fullname的屬性,而不是新創(chuàng)建一個(gè)節(jié)點(diǎn):
    3,一種可選的方式:
    首先,為Person創(chuàng)建一個(gè)toString方法,里面包含了所有能用來(lái)重新創(chuàng)建一個(gè)Person實(shí)例的數(shù)據(jù):

    package com.thoughtworks.xstream.examples;
    public class Person {
    private String name;
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public String toString() {
    return getName();
    }
    }

    現(xiàn)在,我們就能把我們的轉(zhuǎn)化器簡(jiǎn)寫為:

     

    package com.thoughtworks.xstream.examples;
    import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
    public class PersonConverter extends AbstractSingleValueConverter {
    public boolean canConvert(Class clazz) {
    return clazz.equals(Person.class);
    }
    public Object fromString(String str) {
    Person person = new Person();
    person.setName(string);
    return person;
    }
    }

    現(xiàn)在,輸出的XML也會(huì)變得更易讀(為person創(chuàng)建別名person之后):

    <person>Guilherme</person>
    名字變成了一個(gè)內(nèi)置的值,而不是一個(gè)單獨(dú)的節(jié)點(diǎn)。
    4,轉(zhuǎn)換Date:
    我們已經(jīng)知道Converter接口是怎樣工作的了,現(xiàn)在我們來(lái)創(chuàng)建一個(gè)使用Locale對(duì)象轉(zhuǎn)換時(shí)間的轉(zhuǎn)換器:
    在我們的轉(zhuǎn)換器構(gòu)造方法中,我們將傳入一個(gè)Locale對(duì)象,該Locale對(duì)象會(huì)作為一個(gè)成員屬性被轉(zhuǎn)換器持有:

    package com.thoughtworks.xstream.examples;
    import java.util.Locale;
    import com.thoughtworks.xstream.converters.Converter;
    import com.thoughtworks.xstream.converters.MarshallingContext;
    import com.thoughtworks.xstream.converters.UnmarshallingContext;
    import com.thoughtworks.xstream.io.HierarchicalStreamReader;
    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
    public class DateConverter implements Converter {
    private Locale locale;
    public DateConverter(Locale locale) {
    super();
    this.locale = locale;
    }
    public boolean canConvert(Class clazz) {
    return false;
    }
    public void marshal(Object value, HierarchicalStreamWriter writer,
    MarshallingContext context) {
    }
    public Object unmarshal(HierarchicalStreamReader reader,
    UnmarshallingContext context) {
    return null;
    }
    }

    現(xiàn)在,讓我們能轉(zhuǎn)換任何繼承了Calendar對(duì)象的類:

    public boolean canConvert(Class clazz) {
            return Calendar.class.isAssignableFrom(clazz);
    }
    首先,我們來(lái)將Calendar轉(zhuǎn)換成本地化的字符串:首先我們把object轉(zhuǎn)化成Calendar,得到Date對(duì)象,并使用DataFormatter來(lái)得到一個(gè)本地化的時(shí)間:

    public void marshal(Object value, HierarchicalStreamWriter writer,
    MarshallingContext context) {
    Calendar calendar = (Calendar) value;
    // grabs the date
    Date date = calendar.getTime();
    // grabs the formatter
    DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
    this.locale);
    // formats and sets the value
    writer.setValue(formatter.format(date));
    }

    另一方面,在unmarshall方法中,我們創(chuàng)建了一個(gè)GregorianCalendar,得到本地化的DataFormat實(shí)例,將字符串轉(zhuǎn)換成Date對(duì)象,并賦值給GregorianCalendar。

    public Object unmarshal(HierarchicalStreamReader reader,
                    UnmarshallingContext context) {
            // creates the calendar
            GregorianCalendar calendar = new GregorianCalendar();
            // grabs the converter
            DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
                            this.locale);
            // parses the string and sets the time
            try {
                    calendar.setTime(formatter.parse(reader.getValue()));
            } catch (ParseException e) {
                    throw new ConversionException(e.getMessage(), e);
            }
            // returns the new object
            return calendar;
    }

    注意:
    1,記住一些DataFormat實(shí)現(xiàn)不是線程安全的,所以,不要讓你的轉(zhuǎn)換器持有DataFormat的引用
    2,在經(jīng)過(guò)了保存和加載的過(guò)程后,該轉(zhuǎn)換器可以將其他Calendar實(shí)現(xiàn)轉(zhuǎn)換為GregorianCalendar。如果這不是你希望的,只需要修改canConvert方法,并在類型只有為GregorianCalendar的時(shí)候再返回true。
    現(xiàn)在,我們得到了下面這個(gè)轉(zhuǎn)換器:

    package com.thoughtworks.xstream.examples;
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.GregorianCalendar;
    import java.util.Locale;
    import com.thoughtworks.xstream.converters.ConversionException;
    import com.thoughtworks.xstream.converters.Converter;
    import com.thoughtworks.xstream.converters.MarshallingContext;
    import com.thoughtworks.xstream.converters.UnmarshallingContext;
    import com.thoughtworks.xstream.io.HierarchicalStreamReader;
    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
    public class DateConverter implements Converter {
    private Locale locale;
    public DateConverter(Locale locale) {
    super();
    this.locale = locale;
    }
    public boolean canConvert(Class clazz) {
    return Calendar.class.isAssignableFrom(clazz);
    }
    public void marshal(Object value, HierarchicalStreamWriter writer,
    MarshallingContext context) {
    Calendar calendar = (Calendar) value;
    Date date = calendar.getTime();
    DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
    this.locale);
    writer.setValue(formatter.format(date));
    }
    public Object unmarshal(HierarchicalStreamReader reader,
    UnmarshallingContext context) {
    GregorianCalendar calendar = new GregorianCalendar();
    DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
    this.locale);
    try {
    calendar.setTime(formatter.parse(reader.getValue()));
    } catch (ParseException e) {
    throw new ConversionException(e.getMessage(), e);
    }
    return calendar;
    }
    }

    現(xiàn)在,我們來(lái)測(cè)試一下,創(chuàng)建一個(gè)main方法:
    1,創(chuàng)建一個(gè)calendar,
    2,創(chuàng)建XStream對(duì)象
    3,注冊(cè)該轉(zhuǎn)換器,并使用Brazilian Portuguese本地化對(duì)象
    4,將對(duì)象轉(zhuǎn)化成XML
    代碼如下:

    package com.thoughtworks.xstream.examples;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.Locale;
    import com.thoughtworks.xstream.XStream;
    import com.thoughtworks.xstream.io.xml.DomDriver;
    public class DateTest {
    public static void main(String[] args) {
    // grabs the current date from the virtual machine
    Calendar calendar = new GregorianCalendar();
    // creates the xstream
    XStream xStream = new XStream(new DomDriver());
    // brazilian portuguese locale
    xStream.registerConverter(new DateConverter(new Locale("pt", "br")));
    // prints the result
    System.out.println(xStream.toXML(calendar));
    }
    }

     可以得到類似如下的結(jié)果:

    <gregorian-calendar>Sexta-feira, 10 de Fevereiro de 2006</gregorian-calendar>
    注意,我們沒(méi)有為GregorianCalendar創(chuàng)建任何別名,而gregorian-calendar就是默認(rèn)的名字。
    下面我們來(lái)試試unmarshal 方法:

    // loads the calendar from the string
    Calendar loaded = (Calendar) xStream
                    .fromXML("<gregorian-calendar>Sexta-feira, 10 de Fevereiro de 2006</gregorian-calendar>");
    然后打印出該日期:

    // prints using the system defined locale
    System.out.println(DateFormat.getDateInstance(DateFormat.SHORT).format(
                    loaded.getTime()));
    得到的結(jié)果為:

    2/10/06
    5,復(fù)雜的轉(zhuǎn)換器:
    創(chuàng)建另一個(gè)例子:
    我們已經(jīng)創(chuàng)建了兩個(gè)對(duì)象了,現(xiàn)在把它們組合起來(lái):

    package com.thoughtworks.xstream.examples;
    public class Birthday {
    private Person person;
    private Calendar date;
    public Person getPerson() {
    return person;
    }
    public void setPerson(Person person) {
    this.person = person;
    }
    public Calendar getDate() {
    return date;
    }
    public void setDate(Calendar date) {
    this.date = date;
    }
    }

     要轉(zhuǎn)換該類,XStream一點(diǎn)問(wèn)題都沒(méi)有。這里,我們實(shí)現(xiàn)自己的轉(zhuǎn)換器主要是為了驗(yàn)證,在這里,我們想重用我們剛才的PersonConverter和CalendarConverter。canConvert仍然很簡(jiǎn)單,不過(guò)這里,我們不需要再為每一個(gè)屬性重新寫轉(zhuǎn)換方法了,我們只需要使用已經(jīng)注冊(cè)了的轉(zhuǎn)換器來(lái)完成轉(zhuǎn)換:

    package com.thoughtworks.xstream.examples;
    import java.util.Calendar;
    import com.thoughtworks.xstream.converters.Converter;
    import com.thoughtworks.xstream.converters.MarshallingContext;
    import com.thoughtworks.xstream.converters.UnmarshallingContext;
    import com.thoughtworks.xstream.io.HierarchicalStreamReader;
    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
    public class BirthdayConverter implements Converter {
    public boolean canConvert(Class clazz) {
    return Birthday.class == clazz;
    }
    public void marshal(Object value, HierarchicalStreamWriter writer,
    MarshallingContext context) {
    Birthday birthday = (Birthday)value;
    if (value.getPerson() != null) {
    writer.startNode("person");
    context.convertAnother(value.getPerson());
    writer.endNode();
    }
    if (value.getDate() != null) {
    writer.startNode("birth");
    context.convertAnother(value.getDate());
    writer.endNode();
    }
    }
    public Object unmarshal(HierarchicalStreamReader reader,
    UnmarshallingContext context) {
    Birthday birthday = new Birthday();
    while (reader.hasMoreChildren()) {
    reader.moveDown();
    if ("person".equals(reader.getNodeName())) {
    Person person = (Person)context.convertAnother(birthday, Person.class);
    birthday.setPerson(person);
    } else if ("birth".equals(reader.getNodeName())) {
    Calendar date = (Calendar)context.convertAnother(birthday, Calendar.class);
    birthday.setDate(date);
    }
    reader.moveUp();
    }
    return birthday;
    }
    }

     如果birthday實(shí)例能夠確保不會(huì)出現(xiàn)null值,那么我們就可以去掉marshal和unmarshal方法中對(duì)null情況的判斷,也不需要循環(huán),而直接根據(jù)tag的名字進(jìn)行解析:

    package com.thoughtworks.xstream.examples;
    import java.util.Calendar;
    import com.thoughtworks.xstream.converters.Converter;
    import com.thoughtworks.xstream.converters.MarshallingContext;
    import com.thoughtworks.xstream.converters.UnmarshallingContext;
    import com.thoughtworks.xstream.io.HierarchicalStreamReader;
    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
    public class BirthdayConverter implements Converter {
    public boolean canConvert(Class clazz) {
    return Birthday.class == clazz;
    }
    public void marshal(Object value, HierarchicalStreamWriter writer,
    MarshallingContext context) {
    Birthday birthday = (Birthday)value;
    writer.startNode("person");
    context.convertAnother(value.getPerson());
    writer.endNode();
    writer.startNode("birth");
    context.convertAnother(value.getDate());
    writer.endNode();
    }
    public Object unmarshal(HierarchicalStreamReader reader,
    UnmarshallingContext context) {
    Birthday birthday = new Birthday();
    reader.moveDown();
    Person person = (Person)context.convertAnother(birthday, Person.class);
    birthday.setPerson(person);
    reader.moveUp();
    reader.moveDown();
    Calendar date = (Calendar)context.convertAnother(birthday, Calendar.class);
    birthday.setDate(date);
    reader.moveUp();
    return birthday;
    }
    }

    posted on 2010-09-07 21:24 w@ns0ng 閱讀(517) 評(píng)論(0)  編輯  收藏 所屬分類: java

    主站蜘蛛池模板: 一区二区三区在线免费 | 色屁屁www影院免费观看视频 | 久久国产精品亚洲综合| 57pao国产成视频免费播放| 亚洲aⅴ天堂av天堂无码麻豆| 久久亚洲AV永久无码精品| 色欲色香天天天综合网站免费| 亚洲中文字幕日本无线码| 亚洲午夜成人精品电影在线观看| 99免费在线观看视频| 亚洲AV无码一区二区三区电影| 日本红怡院亚洲红怡院最新| 最近的中文字幕大全免费版| 国产又黄又爽又大的免费视频| 香蕉大伊亚洲人在线观看| 亚洲精品无码av人在线观看| 毛色毛片免费观看| 国产无遮挡无码视频免费软件 | 亚洲第一成人在线| 精品国产人成亚洲区| 在线v片免费观看视频| 最新久久免费视频| 亚洲精品无码成人片久久不卡| 亚洲成A人片在线观看WWW| 国产大片91精品免费看3| 2019中文字幕在线电影免费| 一级**爱片免费视频| 亚洲中文字幕久久久一区| 亚洲成年轻人电影网站www| 亚洲Av无码乱码在线播放| 国产精品久久久久久久久久免费| a级毛片免费播放| 美女隐私免费视频看| 亚洲成年网站在线观看| 久久亚洲国产午夜精品理论片| 亚洲国产一区明星换脸| 嫩草影院在线免费观看| 四虎在线成人免费网站| 久久国产精品国产自线拍免费| 一级特黄特色的免费大片视频| 亚洲色大成网站www永久网站|