【问题标题】:XStream serialize custom Map with NamedMapConverterXStream 使用 NamedMapConverter 序列化自定义地图
【发布时间】:2015-08-30 11:46:24
【问题描述】:

我成功地将包含HashMap<String, String>Base 类与NamedMapConverter 序列化。我的要求发生了变化,我需要将 HashMap 更改为扩展 HashMap<String, String> 的自定义 StringDictionary 类。

但是在使用StringDictionary 之后,我的序列化被破坏了。有没有办法在不编写自定义转换器的情况下配置 XStream 和/或 NamedMapConverter 以保留所需的 xml 输出?

在 Android 上使用 XStream 1.4.7。


必需的xml 输出:

<base>
  <values>
    <val key="123">111</val>
    <val key="abc">aaa</val>
  </values>
</base>

Base 类与 HashMapXStream 配置产生上述输出

public class Base
{
    public Map<String, String> values = new HashMap<>();
}


Base base = new Base();
base.values.put("abc", "aaa");
base.values.put("123", "111");

XStream xs = new XStream();
xs.alias("base", Base.class);
NamedMapConverter c = new NamedMapConverter(xs.getMapper(), "val", "key", String.class, null, String.class, true, false, xs.getConverterLookup());
xs.registerConverter(c);

String s = xs.toXML(base);

使用修改后的Base

public class Base
{
    public Map<String, String> values = new StringDictionary();
}

产生以下不正确的xml 输出:

<base>
  <values class="com.test.StringDictionary" serialization="custom">
    <unserializable-parents/>
    <map>
      <default>
        <loadFactor>0.75</loadFactor>
      </default>
      <int>4</int>
      <int>2</int>
      <string>123</string>
      <string>111</string>
      <string>abc</string>
      <string>aaa</string>
    </map>
  </values>
</base>

【问题讨论】:

    标签: java android xstream


    【解决方案1】:

    似乎没有上面的自定义转换器是不可能实现的。但是,在这种情况下,只需对现有转换器进行轻微调整即可提供自定义转换器。问题在于必须覆盖NamedMapConverter.canConvert 方法以包含自定义StringDictionary 类。

    以下代码将为修改后的Base 类生成所需的xml 输出:

    XStream xs = new XStream();
    xs.alias("base", Base.class);
    
    xs.addDefaultImplementation(StringDictionary.class, Map.class);
    NamedMapConverter c = new NamedMapConverter(xs.getMapper(), "val", "key", String.class, null, String.class, true, false, xs.getConverterLookup())
    {
        public boolean canConvert(Class type)
        {
            if (type.equals(StringDictionary.class)) return true;
            else return super.canConvert(type);
        }
    };
    xs.registerConverter(c);
    

    另一个更简单(但不完全兼容)的解决方案是将StringDictionary 类传递给NamedMapConverter 构造函数。但是这个解决方案会稍微改变xml 的输出。

    XStream xs = new XStream();
    xs.alias("base", Base.class);
    NamedMapConverter c = new NamedMapConverter(StringDictionary.class, xs.getMapper(), "val", "key", String.class, null, String.class, true, false, xs.getConverterLookup());
    xs.registerConverter(c);
    
    
    <base>
      <values class="com.test.StringDictionary">
        <val key="123">111</val>
        <val key="abc">aaa</val>
      </values>
    </base>
    

    【讨论】:

      猜你喜欢
      • 2010-12-19
      • 1970-01-01
      • 2019-12-14
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      相关资源
      最近更新 更多