Вы можете использовать функцию MixIn
и динамически объявлять имя для корневого типа:
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 {
}
Выше кода печатается:
<ExistingName><commonVar1>Var1</commonVar1><commonVar2>Var2</commonVar2><commonVar3>Var3</commonVar3></ExistingName>
<BrandNewName><commonVar1>Var1</commonVar1><commonVar2>Var2</commonVar2><commonVar3>Var3</commonVar3></BrandNewName>
Но мы также можем создать дополнительную POJO
сохранить объект и имя, которое мы хотим присвоить в процессе сериализации. Чтобы заставить его работать, нам нужно реализовать пользовательский JsonSerializer
и реализовать это поведение. Пример решения может выглядеть следующим образом:
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 +
'}';
}
}
Над отпечатками кода:
<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>