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

本文介绍如何通过自定义Converter优化XStream库中Map类型的序列化过程,提供了一种简洁的方法来改善序列化输出格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天用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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值