XStream序列化对象,java.util.Map自定义Converter

如果你不知道XStream是什么东东,请看我以前的一篇文章:

http://fuliang.iteye.com/blog/379429

 

今天用XStream序列化对象,其中有Map类型的字段,结果不让人满意

Xml代码   收藏代码
  1. <ExtractResult>  
  2.  <dataRecords>  
  3.    <DataRecord>  
  4.      <properties>  
  5.        <property>  
  6.          <string>region</string>  
  7.          <string>非洲中东</string>  
  8.        </property>  
  9.        <property>  
  10.          <string>routeReference</string>  
  11.          <string>首都机场集合,搭乘土耳其航空直飞伊斯坦布尔,夜宿机上。</string>  
  12.        </property>  
  13.        <property>  
  14.          <string>routeDays</string>  
  15.          <string>10</string>  
  16.        </property>  
  17.        <property>  
  18.          <string>price</string>  
  19.          <string>¥13500起</string>  
  20.        </property>  
  21.        <property>  
  22.          <string>subject</string>  
  23.          <string>常规</string>  
  24.        </property>  
  25.        <property>  
  26.          <string>dayOfBookingExpired</string>  
  27.          <string>2010-02-01</string>  
  28.        </property>  
  29.        <property>  
  30.          <string>departure</string>  
  31.          <string>北京</string>  
  32.        </property>  
  33.        <property>  
  34.          <string>dayOfDeparture</string>  
  35.          <string>2010-02-10</string>  
  36.        </property>  
  37.        <property>  
  38.          <string>title</string>  
  39.          <string>[团队游]埃及土耳其10日千年文明之旅(春节)</string>  
  40.        </property>  
  41.      </properties>  
  42.    </DataRecord>  
  43.  </dataRecords>  
  44. lt;/ExtractResult>  

其中的key和value被序列化成:

 

Xml代码   收藏代码
  1. <string>region</string>  
  2. <string>非洲中东</string>  

我比较想要的结果是

 

Java代码   收藏代码
  1. <property key="region" value="非洲中东"/>  

查看了XStream的文档,可以通过自定义Converter来转换,经过尝试,只需要很简单的步骤就可以完成:

 

Java代码   收藏代码
  1. import java.util.HashMap;  
  2. import java.util.Hashtable;  
  3. import java.util.Iterator;  
  4. import java.util.Map;  
  5. import java.util.Map.Entry;  
  6.   
  7. import com.thoughtworks.xstream.converters.MarshallingContext;  
  8. import com.thoughtworks.xstream.converters.UnmarshallingContext;  
  9. import com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter;  
  10. import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper;  
  11. import com.thoughtworks.xstream.io.HierarchicalStreamReader;  
  12. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;  
  13. import com.thoughtworks.xstream.mapper.Mapper;  
  14.   
  15. /** 
  16.  * @author fuliang 
  17.  *  
  18.  */  
  19. public class MapCustomConverter extends AbstractCollectionConverter {  
  20.   
  21.     /** 
  22.      * @param mapper 
  23.      */  
  24.     public MapCustomConverter(Mapper mapper) {  
  25.         super(mapper);  
  26.     }  
  27.   
  28.     public boolean canConvert(Class type) {  
  29.         return type.equals(HashMap.class)  
  30.                 || type.equals(Hashtable.class)  
  31.                 || type.getName().equals("java.util.LinkedHashMap")  
  32.                 || type.getName().equals("sun.font.AttributeMap"// Used by java.awt.Font in JDK 6  
  33.                 ;  
  34.     }  
  35.   
  36.     public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {  
  37.         Map map = (Map) source;  
  38.         for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {  
  39.             Entry entry = (Entry) iterator.next();  
  40.             ExtendedHierarchicalStreamWriterHelper.startNode(writer, "property", Entry.class);  
  41.   
  42.             writer.addAttribute("key",  entry.getKey().toString());  
  43.             writer.addAttribute("value", entry.getValue().toString());  
  44.             writer.endNode();  
  45.         }  
  46.     }  
  47.   
  48.     public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {  
  49.         Map map = (Map) createCollection(context.getRequiredType());  
  50.         populateMap(reader, context, map);  
  51.         return map;  
  52.     }  
  53.   
  54.     protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Map map) {  
  55.         while (reader.hasMoreChildren()) {  
  56.             reader.moveDown();  
  57.             Object key = reader.getAttribute("key");  
  58.             Object value = reader.getAttribute("value");  
  59.             map.put(key, value);  
  60.             reader.moveUp();  
  61.         }  
  62.     }  
  63. }  

然后这么使用:

Java代码   收藏代码
  1. XStream xStream = new XStream();  
  2. xStream.registerConverter(new MapCustomConverter(new DefaultMapper(XmlOutputFormatter.class.getClassLoader())));  
  3. xStream.alias("DataRecord", ExtractDataRecord.class);  
  4. xStream.alias("ExtractResult", ExtractResult.class);  
  5. xStream.alias("property", Entry.class);  
  6. return xStream.toXML(extractResult);  
 

序列化后的结果很漂亮:

 

Java代码   收藏代码
  1. <ExtractResult>  
  2.   <dataRecords>  
  3.     <DataRecord>  
  4.       <properties>  
  5.         <property key="region" value="港澳"/>  
  6.         <property key="routeReference" value="搭乘国际航班直飞桃园国际机场,办理相关手续后,前往用晚餐。前往酒店入住休息。"/>  
  7.         <property key="routeDays" value="8"/>  
  8.         <property key="price" value="¥5680起"/>  
  9.         <property key="subject" value="常规"/>  
  10.         <property key="dayOfBookingExpired" value="2010-01-15"/>  
  11.         <property key="departure" value="北京"/>  
  12.         <property key="dayOfDeparture" value="2010-01-25"/>  
  13.         <property key="title" value="[团队游]台湾8日宝岛乡情之旅"/>  
  14.       </properties>  
  15.     </DataRecord>  
  16.   </dataRecords>  
  17. </ExtractResult>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值