2

SimpleでHashMapを拡張する要素をシリアル化したい。

@Root(name = "settings")
@ElementMap(entry="element", key="id", attribute=true, required=true, empty=true)
public class Settings extends HashMap<String, Object> {

    ...

シリアル化するたびにエラーは発生しませんが、次のような空のファイルも取得します。

<settings/>

代わりに内部オブジェクトを作成せずにこれを行う方法はありますか?その後、すべてのメソッドをそれに委任する必要がありますか?

4

1 に答える 1

1

その理由は、SimpleがHashMapsを変換できないためだと思います。

このコードを実行すると...

    Map<String, Object> map = new HashMap<>();
    map.put("a", "b");
    map.put("c", 3);
    map.put("d", new Date());


    ser.write(map, new File("test2.xml"));

...次の例外が発生します。

org.simpleframework.xml.transform.TransformException: Transform of class java.util.HashMap not supported


さて、これがあなたのクラスをシリアル化するために私がしたことです:

変換に使用するコンバーターを作成しましたSettings

Converterクラス:

public class SettingsConverter implements Converter<Settings>
{
    private Transformer transformer;


    public SettingsConverter()
    {
        this.transformer = new Transformer(new RegistryMatcher());
    }



    @Override
    public Settings read(InputNode node) throws Exception
    {
        Settings settings = new Settings();
        InputNode child = node.getNext();

        while( child != null )
        {
            final String key = child.getAttribute("key").getValue();
            final Class c = Class.forName(child.getAttribute("class").getValue());

            settings.put(key, transformer.read(child.getAttribute("value").getValue(), c));
            child = node.getNext();
        }

        return settings;
    }


    @Override
    public void write(OutputNode node, Settings value) throws Exception
    {
        for( Map.Entry<String, Object> entry : value.entrySet() )
        {
            OutputNode child = node.getChild("setting");

            child.setAttribute("key", entry.getKey());
            child.setAttribute("class", entry.getValue().getClass().getName());
            child.setAttribute("value", transformer.write(entry.getValue(), entry.getValue().getClass())); 
        }   
    }
}

Settingsクラス:

@Root()
@Convert(value=SettingsConverter.class)
public class Settings extends HashMap<String, Object>
{
    // ...
}

テスト:

final File testFile = new File("test.xml");

Settings settings = new Settings();
settings.put("a", "b");
settings.put("c", 3);
settings.put("d", new Date());

// Serialize - make shure you use an AnnotationStrategy here
Serializer ser = new Persister(new AnnotationStrategy());
ser.write(settings, testFile); 


// Deserialize
Settings in = ser.read(Settings.class, testFile);

System.out.println(settings.equals(in));

ファイルtest.xml:

<settings>
   <setting key="d" class="java.util.Date" value="2012-08-28 17:15:13.152 MESZ"/>
   <setting key="c" class="java.lang.Integer" value="3"/>
   <setting key="a" class="java.lang.String" value="b"/>
</settings>

これを行うにはもっと良い方法があると思いますが(それ以上ではないにしても)、おそらくこれは少し役に立ちます。

もう1つのポイントは、@Defaultここでは注釈が機能しないことです(例外)。これを解決すると、問題全体が解決する可能性があります。

于 2012-08-28T15:16:28.893 に答える