You can use MixIn
feature and dynamically declare name for root type:
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
public class XmlMapperApp {
public static void main(String[] args) throws Exception {
XmlMapper xmlMapperOld = new XmlMapper();
xmlMapperOld.addMixIn(MyPojo.class, MyPojoExistingNameMinIn.class);
XmlMapper xmlMapperNew = new XmlMapper();
xmlMapperNew.addMixIn(MyPojo.class, MyPojoBranNewNameMinIn.class);
System.out.println(xmlMapperOld.writeValueAsString(new MyPojo()));
System.out.println(xmlMapperNew.writeValueAsString(new MyPojo()));
}
}
@JacksonXmlRootElement(localName = "ExistingName")
interface MyPojoExistingNameMinIn {
}
@JacksonXmlRootElement(localName = "BrandNewName")
interface MyPojoBranNewNameMinIn {
}
Above code prints:
<ExistingName><commonVar1>Var1</commonVar1><commonVar2>Var2</commonVar2><commonVar3>Var3</commonVar3></ExistingName>
<BrandNewName><commonVar1>Var1</commonVar1><commonVar2>Var2</commonVar2><commonVar3>Var3</commonVar3></BrandNewName>
But we can also create an extra POJO
to store object and name we want to assign during serialisation process. To make it work we need to implement custom JsonSerializer
and implement that behaviour. Example solution could look like below:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.util.NameTransformer;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializer;
import javax.xml.namespace.QName;
import java.io.IOException;
import java.util.Objects;
public class XmlMapperApp {
public static void main(String[] args) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
for (char c = 65; c < 70; c++) {
System.out.println(xmlMapper.writeValueAsString(new PersistAs("ExistingName_" + c, new MyPojo())));
}
}
}
class PersistAsJsonSerializer extends JsonSerializer<PersistAs> {
@Override
public void serialize(PersistAs value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
ToXmlGenerator xmlGen = (ToXmlGenerator) gen;
// set desired name
xmlGen.setNextName(new QName(value.getName()));
xmlGen.writeStartObject();
// serialise fields
XmlBeanSerializer serializer = (XmlBeanSerializer) serializers.findValueSerializer(value.getValue().getClass());
JsonSerializer<Object> unwrappingSerializer = serializer.unwrappingSerializer(NameTransformer.NOP);
unwrappingSerializer.serialize(value.getValue(), gen, serializers);
// end of root
gen.writeEndObject();
}
}
@JsonSerialize(using = PersistAsJsonSerializer.class)
class PersistAs {
private final String name;
private final Object value;
public PersistAs(String name, Object value) {
this.name = Objects.requireNonNull(name);
this.value = Objects.requireNonNull(value);
}
public String getName() {
return name;
}
public Object getValue() {
return value;
}
@Override
public String toString() {
return "PersistAs{" +
"name='" + name + '\'' +
", value=" + value +
'}';
}
}
Above code prints:
<ExistingName_A><commonVar1>Var1</commonVar1><commonVar2>Var2</commonVar2><commonVar3>Var3</commonVar3></ExistingName_A>
<ExistingName_B><commonVar1>Var1</commonVar1><commonVar2>Var2</commonVar2><commonVar3>Var3</commonVar3></ExistingName_B>
<ExistingName_C><commonVar1>Var1</commonVar1><commonVar2>Var2</commonVar2><commonVar3>Var3</commonVar3></ExistingName_C>
<ExistingName_D><commonVar1>Var1</commonVar1><commonVar2>Var2</commonVar2><commonVar3>Var3</commonVar3></ExistingName_D>
<ExistingName_E><commonVar1>Var1</commonVar1><commonVar2>Var2</commonVar2><commonVar3>Var3</commonVar3></ExistingName_E>