XSTREAM支持好几种方式的序列化(XML、JSON、BIN),几种方式都有其鲜明的优点:
1)XML方式最容易阅读,且应用范围比较广。
2)JSON方式便于WEB上的传输
3)BIN方式的性能最好,占用的空间也比较少
在反序列化时,由于类的结构发生变化导致一些属性不存在了,可以通过下面的方式对于不存在的属性予以忽略:
private static final XStream DESERIALIZE_XSTREAM = new XStream() { /** * 忽略不存在的属性 */ protected MapperWrapper wrapMapper(MapperWrapper next) { return new MapperWrapper(next) { public Class> realClass(String elementName) { try { return super.realClass(elementName); } catch (CannotResolveClassException crce) { return null; } } }; } };
XSTREAM序列化时会带上类的全路径,比较不好看也占用空间,可以通过别名的方式简化
static { final DatasetSerializer dsSerializer = new DatasetSerializer(); final DateSerializer dtSerializer = new DateSerializer(); SERIALIZE_XSTREAM.alias("MP", Map.class); SERIALIZE_XSTREAM.alias("DS", Dataset.class); SERIALIZE_XSTREAM.alias("ST", String.class); SERIALIZE_XSTREAM.registerConverter(dsSerializer); SERIALIZE_XSTREAM.registerConverter(dtSerializer); SERIALIZE_XSTREAM.setMode(XStream.NO_REFERENCES); DESERIALIZE_XSTREAM.alias("MP", Map.class); DESERIALIZE_XSTREAM.alias("DS", Dataset.class); DESERIALIZE_XSTREAM.alias("ST", String.class); DESERIALIZE_XSTREAM.registerConverter(dsSerializer); DESERIALIZE_XSTREAM.registerConverter(dtSerializer); DESERIALIZE_XSTREAM.setMode(XStream.NO_REFERENCES); }
使用BIN的方式序列化和反序列化对象:
public static final byte[] serialize(XStream xstream, Object obj, boolean compress) { ByteArrayOutputStream bos = new ByteArrayOutputStream(4096); xstream.marshal(obj, new BinaryStreamWriter(bos)); //xstream.marshal(obj, new CompactWriter(new OutputStreamWriter(bos))); if (compress) { return compress(bos.toByteArray()); } else { return bos.toByteArray(); } } /** * 从XML byte数组中反序列化出一个对象 * * @param bytes * @return */ public static final Object deserialize(byte[] bytes, boolean decompress) { byte[] newBytes; if (decompress) { newBytes = decompress(bytes); } else { newBytes = bytes; } ByteArrayInputStream bis = new ByteArrayInputStream(newBytes); BinaryStreamReader bsr = new BinaryStreamReader(bis); return DESERIALIZE_XSTREAM.unmarshal(bsr); }
XSTREAM序列化通过反射来获取对象属性值,一方面反射效率相对较慢,另一方面不是所有的属性都需要序列化。可以通过自己实现特定类的序列化来提高效率。
public class DatasetSerializer implements Converter { @SuppressWarnings("unchecked") public void marshal(Object obj, HierarchicalStreamWriter writer, MarshallingContext context) { Dataset ds = (Dataset) obj; Listrecords = ds.getRecordList(); if (!CollectionUtil.isEmpty(records)) { for (Record record : records) { writer.startNode("RC"); Map map = record.getNewDatasMap(); context.convertAnother(map); writer.endNode(); } } } @SuppressWarnings("unchecked") public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { Dataset ds = new Dataset(); while (reader.hasMoreChildren()) { reader.moveDown(); Record r = ds.newRecord(); if (reader.hasMoreChildren()) { Map m = (Map ) context.convertAnother(reader, Map.class); r.setNewDatasMap(m); } reader.moveUp(); } return ds; } @SuppressWarnings("unchecked") public boolean canConvert(Class cls) { return cls.equals(Dataset.class); } } public class DateSerializer implements Converter { public void marshal(Object dt, HierarchicalStreamWriter writer, MarshallingContext ctx) { Date date = (Date) dt; writer.setValue(String.valueOf(date.getTime())); } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext ctx) { Long time = Long.valueOf(reader.getValue()); return new Date(time); } @SuppressWarnings("unchecked") public boolean canConvert(Class cls) { return cls.equals(Date.class); } }