在对象和xml映射时候,有些类型需要我们制定格式转换,此时就要自定义转换器了。
下面创建一个对于Date进行转换的一个日期转换器。
DateConverter
package cn.framework.t1;
import java.text.DateFormat;
import java.text.ParseException;
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;
}
//判断需要转换的类型
@Override
public boolean canConvert(Class clazz) {
// TODO Auto-generated method stub
return Date.class.isAssignableFrom(clazz);
}
//编写java对象到xml的逻辑
@Override
public void marshal(Object value, HierarchicalStreamWriter writer,
MarshallingContext context) {
DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,this.locale);
writer.setValue(formatter.format(value));
}
//编写xml到java对象的逻辑
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
GregorianCalendar calendar = new GregorianCalendar();
DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,this.locale);
try{
calendar.setGregorianChange(formatter.parse(reader.getValue()));
}catch(ParseException e){
throw new ConversionException(e.getMessage(),e);
}
return calendar.getGregorianChange();
}
}
marshal 和 unmarshal 中写我们自己的转换逻辑。
接下来,把这个自定义转换器注册到XStream。
package cn.framework.t1;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Locale;
import org.apache.log4j.Logger;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
public class XStreamUtils {
private static final Logger logger=Logger.getLogger("cn.framework.t1.XStreamUtils");
private static XStream xstream;
static{
logger.info("init xstream ...");
xstream=new XStream(new DomDriver());
/*******对生成的xml做一些设置*******/
//设置别名,不设置将采用完全类名
xstream.alias("User", User.class);
xstream.alias("UserLog", UserLog.class);
//设置类成员别名
xstream.aliasField("id", User.class, "userId");
//类的属性默认为xml的元素,现在修改为xml属性
xstream.aliasAttribute(UserLog.class, "logId", "lid");
xstream.useAttributeFor(UserLog.class, "logId");
//只保留集合内元素,去掉上级标签
xstream.addImplicitCollection(User.class, "logs");
//注册自定义转换器
xstream.registerConverter(new DateConverter(Locale.SIMPLIFIED_CHINESE));
}
public static void objectToXML(User user) throws FileNotFoundException{
logger.info("do objectToXML ...");
FileOutputStream fileOutputStream = new FileOutputStream("e:/out/xstream_user.xml");
xstream.toXML(user, fileOutputStream);
}
public static void xmlToObject() throws FileNotFoundException{
logger.info("do xmlToObject ...");
FileInputStream input = new FileInputStream("e:/out/xstream_user.xml");
User user=(User) xstream.fromXML(input);
System.out.println(user);
}
}
使用转换器后,序列化生成的xml:
<User>
<id>1</id>
<userName>aaa</userName>
<pwd>123456</pwd>
<UserLog lid="1">
<ip>127.0.0.1</ip>
</UserLog>
<UserLog lid="2">
<ip>127.0.0.1</ip>
</UserLog>
<lastVisted>2017年12月6日 星期三</lastVisted>
</User>
lastVisted 字段格式已经改变,说明转换成功。