您的位置:首页 > 编程语言 > Java开发

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

2013-05-20 10:50 344 查看
如果你不知道XStream是什么东东,请看我以前的一篇文章:

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

 

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

Xml代码  


<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被序列化成:

 

Xml代码  


<string>region</string>  

<string>非洲中东</string>  

我比较想要的结果是

 

Java代码  


<property key="region" value="非洲中东"/>  

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

 

Java代码  


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();  

        }  

    }  

}  

然后这么使用:

Java代码  


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);  

 

序列化后的结果很漂亮:

 

Java代码  


<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>  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: