XStream 使用 NamedMapConverter 序列化自定义 Map [英] XStream serialize custom Map with NamedMapConverter

查看:33
本文介绍了XStream 使用 NamedMapConverter 序列化自定义 Map的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已成功序列化包含 HashMapBase 类和 NamedMapConverter.我的需求发生了变化,我需要将 HashMap 更改为扩展 HashMap 的自定义 StringDictionary 类.

I am successfully serializing my Base class containing HashMap<String, String> with NamedMapConverter. My requirements have changed and I need to change HashMap to custom StringDictionary class that extends HashMap<String, String>.

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

But after using StringDictionary, my serialization got broken. Is there a way to configure XStream and/or NamedMapConverter to preserve needed xml output without writing custom converters?

在 Android 上使用 XStream 1.4.7.

Using XStream 1.4.7 on Android.

必需的 xml 输出:

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

Base 类,带有 HashMapXStream 配置,产生上述输出

Base class with HashMap and XStream configuration that produces above output

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 输出:

produces following incorrect xml output:

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

推荐答案

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

It seems that without custom converter above is impossible to achieve. However, in this case custom converter can be provided with only slight tweaking of existing one. Problem lies in NamedMapConverter.canConvert method that has to be overridden to include custom StringDictionary class.

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

Following code will produce required xml output for modified Base class:

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 输出.


Another simpler (but not fully compliant) solution, is to pass StringDictionary class to NamedMapConverter constructor. However this solution will slightly change xml output.

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>

这篇关于XStream 使用 NamedMapConverter 序列化自定义 Map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆