One way you can change the XML is to use a JAXB XmlAdapter
. Something like
public class PropertyAdapter extends XmlAdapter<PropertyAdapter.AdaptedProperties,
HashMap<String, PropertyObject>> {
public static class AdaptedProperties {
public ArrayList<PropertyObject> property = new ArrayList<>();
}
@Override
public HashMap<String, PropertyObject> unmarshal(
PropertyAdapter.AdaptedProperties list) throws Exception {
HashMap<String, PropertyObject> map = new HashMap<>();
for (PropertyObject prop: list.property) {
map.put(prop.getName(), prop);
}
return map;
}
@Override
public PropertyAdapter.AdaptedProperties marshal(
HashMap<String, PropertyObject> map) throws Exception {
ArrayList<PropertyObject> list = new ArrayList<>(map.values());
AdaptedProperties props = new AdaptedProperties();
props.property = list;
return props;
}
}
Then just annotate the field/property
@XmlRootElement
public class DTO {
private HashMap<String, PropertyObject> properties;
@XmlJavaTypeAdapter(PropertyAdapter.class)
public HashMap<String, PropertyObject> getProperties() {
return properties;
}
// setter
}
This will be the result. It's not exactly how you want it, but I can't figure out how to get it without the <properties>
wrapper.
<root>
<properties>
<property name="a b c" type="Double" value="2.0"/>
<property name="x y z" type="Double" value="0.0"/>
</properties>
</root>
One thing you also need to make sure of is that when you are using Jackson, you aren't using the provider that has JAXB annotation support configured. If you use this provider, it will use the XmlAdapter
and you will get a JSON array, instead of an object/map like you currently have. Assuming you are using this provider, it has a JacksonJaxbJsonProvider
and a plain JacksonJsonProvider
. You want to make sure to just register the latter.
EDIT
Oh and I forgot to add that the PropertyObject
class I used to test looks like this
@XmlRootElement
public class PropertyObject {
private String name;
@XmlAttribute(name = "name")
public String getName() {
return name;
}
// There are `type` and `value` fields also, with corresponding
// getters and setters, both using the `@XmlAttribute`
}
UPDATE
Let's assume you did want the JAXB annotation support for Jackson JSON serialization. What you can do is configure your own ObjectMapper
, and just use the one with JAXB support for this one class. You can see how that is possible here