XStream学习笔记三

本篇主要讲解XStream的Converter

  1. 简单的Converter

先创建一个简单的pojo类

public class Person {
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return getName();
	}

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

 

 

创建一个Person的Converter

public class PersonConverter implements Converter {

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

	@Override
	public Object unmarshal(HierarchicalStreamReader reader,
			UnmarshallingContext content) {
		Person person=new Person();
		reader.moveDown();
		person.setName(reader.getValue());
		reader.moveUp();
		return person;
	}

	@Override
	public boolean canConvert(Class calzz) {
		return Person.class==calzz;
	}

}

 测试Person的Converter

public class PersonTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Person person=new Person();
		person.setName("张三");
		
		
		XStream stream=new XStream();
		stream.alias("person", Person.class);
		//stream.registerConverter(new PersonConverter());
		
		
		stream.registerConverter(new PersonSingleValueConverter());
		String xml=stream.toXML(person);
		
		System.out.println("xml:"+xml);
		Person p=(Person) stream.fromXML(xml);
		
		String name=p.getName();
		System.out.println("name:"+name);
	}

}

 如果一个只有一个String类型的属性,我们可以用AbstractSingleValueConverter

public class PersonSingleValueConverter extends AbstractSingleValueConverter {

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

	@Override
	public Object fromString(String str) {
		Person person=new Person();
		//System.out.println("str+...."+str);
		person.setName(str);
		return person;
	}

}

 

以上注意方法注意的一点是得重写Person的toString方法

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return getName();
	}

    

2.Date的Converter

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

}

 

注意:

1.DateFormat 的实现有些事非线程安全的,因此不能把它作为Converter的成员变量

2.Calendar.class.isAssignableFrom(clazz);

isAssignableFrom: 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。

public class DateTest {

	/**
	 * @param args
	 */
	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(Locale.CHINA));

        // prints the result
        String xml=xStream.toXML(calendar);
        System.out.println("xml:"+xml);
        
        // loads the calendar from the string
        Calendar loaded = (Calendar) xStream.fromXML(xml);
     // prints using the system defined locale
        System.out.println(DateFormat.getDateInstance(DateFormat.FULL).format(
                        loaded.getTime()));
	}

}

 

 

3.Complex Converter复杂的转换器

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

}

 

Birthday的Converter

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.charAt(0) == 'f') {
                        	 birthday.setGenderFemale();
                         } else if (gender.charAt(0)== 'm') {
                             birthday.setGenderMale();
                         } 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;
 }
}

 看到了没,在有些属性为null时,抛出了自定义的异常,如果能保证所有的属性都是非空的,可以用下面的方式实现Converter

public class BirthdayConverter2 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;
 }
}

 

 

Birthday的测试类

public class BirthdayTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Person person=new Person();
		person.setName("张三");
		
		Calendar date=Calendar.getInstance();
		
		Birthday bir=new Birthday();
		bir.setDate(date);
		bir.setPerson(person);
		bir.setGenderMale();
		
		XStream stream=new XStream();
		stream.alias("birthday", Birthday.class);
		stream.alias("person", Person.class);
		stream.registerConverter(new BirthdayConverter2());
		
		stream.registerConverter(new DateConverter(Locale.CHINA));
		
		
		String xml=stream.toXML(bir);
		
		System.out.println("xml:"+xml);
		
		Birthday b=(Birthday) stream.fromXML(xml);
		
		System.out.println("person.name"+b.getPerson().getName());
		System.out.println(".date:"+DateFormat.getDateInstance(DateFormat.FULL).format(
               b.getDate().getTime()));
		System.out.println(".gender:"+b.getGender());
		

	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值