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>