Using Jackson to serialize a simple type hierarchy:
static class Base {
@JsonProperty
private final int foo = 42;
}
static class Derived extends Base {
@JsonProperty
private final int bar = 39;
}
Using the Jackson XmlMapper I'm getting the following output:
<Derived>
<foo>42</foo>
<bar>39</bar>
</Derived>
What I'd really like to get is XML containing the base type:
<Derived>
<Base>
<foo>42</foo>
</Base>
<bar>39</bar>
</Derived>
I browsed the Jackson API, especially the type annotations and SerializationFeature
, but couldn't figure out how to achieve this.
Any ideas?
I'm looking for a generic approach since I'm dealing with several hundred classes in deeply nested hierarchies.
Update
At least I figured out how to do this using XStream:
public class TypeHierarchyConverter implements Converter {
@Override
public boolean canConvert(@SuppressWarnings("rawtypes") final Class clazz) {
return Base.class.isAssignableFrom(clazz);
}
@Override
public void marshal(final Object value, final HierarchicalStreamWriter writer,
final MarshallingContext context) {
try {
enumerateFields(value, writer, context);
} catch (final IllegalAccessException e) {
e.printStackTrace();
}
}
@Override
public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) {
return null;
}
private void enumerateFields(final Object value, final HierarchicalStreamWriter writer,
final MarshallingContext context) throws IllegalAccessException {
enumerateFields(value, writer, context, value.getClass(), false);
}
private void enumerateFields(final Object value, final HierarchicalStreamWriter writer,
final MarshallingContext context, final Class<?> c, final boolean nest) throws IllegalAccessException {
final String name = c.getSimpleName();
if (nest) {
writer.startNode(name);
}
final Class<?> superclass = c.getSuperclass();
if (!Object.class.equals(superclass)) {
enumerateFields(value, writer, context, superclass, true);
}
final Field[] fields = c.getDeclaredFields();
for (final Field f : fields) {
f.setAccessible(true);
writer.startNode(f.getName());
context.convertAnother(f.get(value));
writer.endNode();
f.setAccessible(false);
}
if (nest) {
writer.endNode();
}
}
}
Still no idea hot to do this with Jackson. :(