如果你不知道XStream是什么东东,请看我以前的一篇文章:
http://fuliang.iteye.com/blog/379429
今天用XStream序列化对象,其中有Map类型的字段,结果不让人满意:
- <ExtractResult>
- <dataRecords>
- <DataRecord>
- <properties>
- <property>
- <string>region</string>
- <string>非洲中东</string>
- </property>
- <property>
- <string>routeReference</string>
- <string>首都机场集合,搭乘土耳其航空直飞伊斯坦布尔,夜宿机上。</string>
- </property>
- <property>
- <string>routeDays</string>
- <string>10</string>
- </property>
- <property>
- <string>price</string>
- <string>¥13500起</string>
- </property>
- <property>
- <string>subject</string>
- <string>常规</string>
- </property>
- <property>
- <string>dayOfBookingExpired</string>
- <string>2010-02-01</string>
- </property>
- <property>
- <string>departure</string>
- <string>北京</string>
- </property>
- <property>
- <string>dayOfDeparture</string>
- <string>2010-02-10</string>
- </property>
- <property>
- <string>title</string>
- <string>[团队游]埃及土耳其10日千年文明之旅(春节)</string>
- </property>
- </properties>
- </DataRecord>
- </dataRecords>
- lt;/ExtractResult>
其中的key和value被序列化成:
- <string>region</string>
- <string>非洲中东</string>
我比较想要的结果是
- <property key="region" value="非洲中东"/>
查看了XStream的文档,可以通过自定义Converter来转换,经过尝试,只需要很简单的步骤就可以完成:
- import java.util.HashMap;
- import java.util.Hashtable;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Map.Entry;
- import com.thoughtworks.xstream.converters.MarshallingContext;
- import com.thoughtworks.xstream.converters.UnmarshallingContext;
- import com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter;
- import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper;
- import com.thoughtworks.xstream.io.HierarchicalStreamReader;
- import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
- import com.thoughtworks.xstream.mapper.Mapper;
- /**
- * @author fuliang
- *
- */
- public class MapCustomConverter extends AbstractCollectionConverter {
- /**
- * @param mapper
- */
- public MapCustomConverter(Mapper mapper) {
- super(mapper);
- }
- public boolean canConvert(Class type) {
- return type.equals(HashMap.class)
- || type.equals(Hashtable.class)
- || type.getName().equals("java.util.LinkedHashMap")
- || type.getName().equals("sun.font.AttributeMap") // Used by java.awt.Font in JDK 6
- ;
- }
- public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
- Map map = (Map) source;
- for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
- Entry entry = (Entry) iterator.next();
- ExtendedHierarchicalStreamWriterHelper.startNode(writer, "property", Entry.class);
- writer.addAttribute("key", entry.getKey().toString());
- writer.addAttribute("value", entry.getValue().toString());
- writer.endNode();
- }
- }
- public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
- Map map = (Map) createCollection(context.getRequiredType());
- populateMap(reader, context, map);
- return map;
- }
- protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Map map) {
- while (reader.hasMoreChildren()) {
- reader.moveDown();
- Object key = reader.getAttribute("key");
- Object value = reader.getAttribute("value");
- map.put(key, value);
- reader.moveUp();
- }
- }
- }
然后这么使用:
- XStream xStream = new XStream();
- xStream.registerConverter(new MapCustomConverter(new DefaultMapper(XmlOutputFormatter.class.getClassLoader())));
- xStream.alias("DataRecord", ExtractDataRecord.class);
- xStream.alias("ExtractResult", ExtractResult.class);
- xStream.alias("property", Entry.class);
- return xStream.toXML(extractResult);
序列化后的结果很漂亮:
- <ExtractResult>
- <dataRecords>
- <DataRecord>
- <properties>
- <property key="region" value="港澳"/>
- <property key="routeReference" value="搭乘国际航班直飞桃园国际机场,办理相关手续后,前往用晚餐。前往酒店入住休息。"/>
- <property key="routeDays" value="8"/>
- <property key="price" value="¥5680起"/>
- <property key="subject" value="常规"/>
- <property key="dayOfBookingExpired" value="2010-01-15"/>
- <property key="departure" value="北京"/>
- <property key="dayOfDeparture" value="2010-01-25"/>
- <property key="title" value="[团队游]台湾8日宝岛乡情之旅"/>
- </properties>
- </DataRecord>
- </dataRecords>
- </ExtractResult>