日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Converter Tutorial

發(fā)布時(shí)間:2025/3/15 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Converter Tutorial 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

Simple Converter

Setting up a simple example

This is the most basic converter... let's start with a simple 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;}}

So let's create a person and convert it to XML...

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));}}

This results in a really ugly XML code which contains the full class name (including package)...

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

So we make use of an 'alias' to change this full class name to something more 'human', for example 'person'.

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

And the outcome is much easier to read (and smaller):

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

Now that we have configured a simple class to play with, let's see what XStream converters can do for us...

Creating a PersonConverter

Let's create a simple converter capable of:

  • telling its capable of converting Person's

  • translating a Person instance in XML

  • translate XML into a new Person

  • We begin creating the PersonConverter class and implementing the Converter interface:

    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;}}

    Now we tell whoever calls us that we can handle only Person's (and?nothing?else, including those classes which extends Person).

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

    The second step is usually quite clean, unless you are dealing with generic converters.

    The marshal method is responsible for translating an object to XML. It receives three arguments:

  • the object we are trying to convert

  • the writer were we should output the data

  • the current marshalling context

  • We start casting the object to person:

    Person?person?=?(Person)?value;

    Now we can output the data... let's start creating a node called?fullname?and adding the person's name to it:

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

    Quite simple huh?

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

    We could have called start/end node as many times as we would like (but remember to close everything you open)... and conversion usually takes place when calling the?setValue?method.

    And now let's go to the unmarshal. We use the?moveDown?and?moveUp?methods to move in the tree hierarchy, so we can simply?moveDown, read the value and?moveUp.

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

    Which gives us the following 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?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;}}

    Now let's register our converter and see how our application?main?method looks like:

    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));}}

    Did you notice how we registered our converter? It's a simple call to?registerConverter:

    xStream.registerConverter(new?PersonConverter());

    The final result is:

    <person><fullname>Guilherme</fullname> </person>

    So you might say... that only changed my tree, I want to convert data!

    Try using an attribute called?fullname?in the?person?tag instead of creating a new child node.

    An alternative for types with String representation

    Let's enhance the Person with a String representation, that contains all necessary text to recreate the instance:

    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();} }

    In this case we can simplify our Converter to

    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;}}

    But even nicer, our XML is also simplified (using the alias for the Person class). Since the String representation is complete, a nested element is not necessary anymore:

    <person>Guilherme</person>

    Note, that in implementation of a SingleValueConverter is required for attributes, since these objects have to be represented by a single string only.

    Date Converter

    Now that we know how the?Converter?interface works, let's create a simple calendar converter which uses the locale to convert the information.

    Our converter will receive the Locale in its constructor and we will keep a reference to it in a member variable:

    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;}}

    Now let's convert anything which extends?Calendar: means if instances of class?clazz?can be assigned to the?Calendar?class, they extends the abstract class?Calendar:

    public?boolean?canConvert(Class?clazz)?{return?Calendar.class.isAssignableFrom(clazz); }

    Let's go for converting a?Calendar?in a localized string... we first cast the object to?Calendar, extract its?Date?and then use a?DateFormat?factory method to get a date converter to our localized string.

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

    And the other way around... in order to unmarshall, we create a?GregorianCalendar, retrieves the localized?DateFormat?instance, parses the string into a?Date?and puts this date in the originalGregorianCalendar:

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

    Note 1: remember that some?DateFormat?implementations are not thread-safe, therefore don't put your formatter as a member of your converter.

    Note 2: this implementation?will?convert other types of Calendar's to GregorianCalendar after save/load. If this is not what you want, change your?canConvert?method to return?true?only if?class?equalsGregorianCalendar.

    So we get the following converter:

    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;}}

    And let's try it out. We create a?DateTest?class with a?main?method:

  • creates a calendar (current date)

  • creates the XStream object

  • registers the converter with a Brazilian Portuguese locale

  • translates the object in XML

  • Well, we already know how to do all those steps... so let's go:

    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?machineCalendar?calendar?=?new?GregorianCalendar();//?creates?the?xstreamXStream?xStream?=?new?XStream(new?DomDriver());//?brazilian?portuguese?localexStream.registerConverter(new?DateConverter(new?Locale("pt",?"br")));//?prints?the?resultSystem.out.println(xStream.toXML(calendar));}}

    The result? Well... it depends, but it will be something like:

    <gregorian-calendar>Sexta-feira,?10?de?Fevereiro?de?2006</gregorian-calendar>

    Note: we did not put any alias as?gregorian-calendar?is the default alias for?GregorianCalendar.

    And now let's try to unmarshal the result shown above:

    //?loads?the?calendar?from?the?string Calendar?loaded?=?(Calendar)?xStream.fromXML("<gregorian-calendar>Sexta-feira,?10?de?Fevereiro?de?2006</gregorian-calendar>");

    And print it using the system locale, short date format:

    //?prints?using?the?system?defined?locale System.out.println(DateFormat.getDateInstance(DateFormat.SHORT).format(loaded.getTime()));

    The result might be something like (if your system locale is American English):

    2/10/06

    Complex Converter

    Setting up another example

    We already defined some classes, so let them glue together:

    package?com.thoughtworks.xstream.examples;public?class?Birthday?{private?Person?person;private?Calendar?date;private?char?gender;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;}public?char?getGender()?{return?gender;}public?void?setGenderMale()?{this.gender?=?'m';}public?void?setGenderFemale()?{this.gender?=?'f';}}

    While XStream is capable of converting this class without any problem, we write our own custom converter just for demonstration. This time we want to reuse our already written converters for the Person and the Calendar and add an own attribute for the gender. The?canConvert?method is plain simple. We convert no derived classes this time, since they might have additional fields. But we reuse the converters registered in XStream for our member fields and handle?null?values:

    package?com.thoughtworks.xstream.examples;import?java.util.Calendar;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?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?(birthday.getGender()?!=?'\0')?{writer.addAttribute("gender",?Character.toString(birthday.getGender()));}if?(birthday.getPerson()?!=?null)?{writer.startNode("person");context.convertAnother(birthday.getPerson());writer.endNode();}if?(birthday.getDate()?!=?null)?{writer.startNode("birth");context.convertAnother(birthday.getDate());writer.endNode();}}public?Object?unmarshal(HierarchicalStreamReader?reader,UnmarshallingContext?context)?{Birthday?birthday?=?new?Birthday();String?gender?=?reader.getAttribute("gender");if?(gender?!=?null)?{if?(gender.length()?>?0)?{??????????????if?(gender.char(0)?==?'f')?{birthday.setGenderFemale();}?else?if?(gender.char(0)?==?'m')?{birthday.setFemale();}?else?{throw?new?ConversionException("Invalid?gender?value:?"?+?gender);}}?else?{throw?new?ConversionException("Empty?string?is?invalid?gender?value");}}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;}}

    The unmarshal method ensures the valid value for the gender by throwing a ConversionException for invalid entries.

    Note, that attributes will always have to be written and read first. You work on a stream and accessing the value of a tag or its members will close the surrounding tag (that is still active when the method is called).

    If the implementation of?Birthday?ensures, that none of its fields could hold a?null?value and gender contains a valid value, then we could drop the?null?condition in the?marshal?method and in?unmarshal?we could omit the loop as well as the comparison of the tag names:

    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.addAttribute("gender",?Character.toString(birthday.getGender()));writer.startNode("person");context.convertAnother(birthday.getPerson());writer.endNode();writer.startNode("birth");context.convertAnother(birthday.getDate());writer.endNode();}public?Object?unmarshal(HierarchicalStreamReader?reader,UnmarshallingContext?context)?{Birthday?birthday?=?new?Birthday();if?(reader.getAttribute("gender").charAt(0)?==?'m')?{birthday.setGenderMale();}?else?{birthday.setGenderFemale();}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;}}

    轉(zhuǎn)載于:https://my.oschina.net/heroShane/blog/199202

    總結(jié)

    以上是生活随笔為你收集整理的Converter Tutorial的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。