XSTREAM序列化与反序列化

使用了XSTREAM的序列化和反序列化,感觉效果不错。

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;
        List<Record> records = ds.getRecordList();
        if (!CollectionUtil.isEmpty(records)) {
            for (Record record : records) {
                writer.startNode("RC");
                Map<String, Object> 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<String, Object> m = (Map<String, Object>) 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);
    }

}

猜你喜欢

转载自rainshow.iteye.com/blog/1076069