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

来源:互联网 发布:天敏智能网络机顶盒 编辑:程序博客网 时间:2024/06/03 20:04

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

该代码是本人从网上收集复制若有侵权问题请与本人联系,我会尽快删除
收集地址为:http://www.xuebuyuan.com/1529910.html

需要引入jar包:xstream-1.3.1.jar

<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>  </ExtractResult>  

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

<string>region</string>  <string>非洲中东</string> 

查看了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());       //方式二            //ExtendedHierarchicalStreamWriterHelper.startNode(writer, entry.getKey().toString(), String.class);//            writer.setValue( 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="北京"/>  

方式二的结果:

<map>  <d>4</d>  <b>2</b>  <c>3</c>  <a>1</a></map>
1 0