问题
I want to serialize an element that extends HashMap with Simple.
@Root(name = "settings")
@ElementMap(entry="element", key="id", attribute=true, required=true, empty=true)
public class Settings extends HashMap<String, Object> {
...
Whenever I serialize it, I get no errors, but I also get an empty file that looks like this:
<settings/>
Is there any way to do this without creating an inner object instead, and then having to delegate all of the methods to it?
回答1:
I suppose the reason is, that Simple cant transform HashMaps.
If i run this code ...
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"));
... i get the following exception:
org.simpleframework.xml.transform.TransformException: Transform of class java.util.HashMap not supported
Now, here is what i did to get your class serialized:
I've written a Converter which is used for transforming Settings
.
The Converter
class:
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()));
}
}
}
The Settings
class:
@Root()
@Convert(value=SettingsConverter.class)
public class Settings extends HashMap<String, Object>
{
// ...
}
Testing:
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));
File 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>
I guess there's a better way (if not some more) to do this, but maybe this helps a bit.
Another point is, @Default
Annotation doesn't work here (Exception), possibly solving this may solve the whole problem
来源:https://stackoverflow.com/questions/9999035/serialize-hashmap-as-root-element-with-simple