具有动态 localName 值的 JacksonXmlRootElement
JacksonXmlRootElement with dynamic localName value
我正在更新我们映射到 XML
的 POJO
,唯一的区别是有人想要旧的 XML
和一些新的,唯一的区别是根包装器名称(所有相同的字段),例如目前,根 Xml 标签设置为 ExistingName
,他们想要一个新值,如 BrandNewName
,具有所有相同的字段。而且还是老样子。有没有办法在 POJO
中翻转这个?
我想我可以通过一些继承和一个带有两个实现的基础 class 来做到这一点,但似乎有点过分了
我知道我可以用 @JacksonXmlRootElement
设置根标签,但是否可以将其设置为变量名。
@JacksonXmlRootElement(localName = 'ExistingName')
class MyPojo {
String commonVar1
String commonVar1
String commonVar1
}
您可以使用 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>
我最终找到 Get Jackson XMLMapper to set root element name in code 并使用
进行设置
XmlMapper mapper = new XmlMapper();
.writer()
.withRootName(myFieldName)
.writeValueAsString(myPojo ));
我正在更新我们映射到 XML
的 POJO
,唯一的区别是有人想要旧的 XML
和一些新的,唯一的区别是根包装器名称(所有相同的字段),例如目前,根 Xml 标签设置为 ExistingName
,他们想要一个新值,如 BrandNewName
,具有所有相同的字段。而且还是老样子。有没有办法在 POJO
中翻转这个?
我想我可以通过一些继承和一个带有两个实现的基础 class 来做到这一点,但似乎有点过分了
我知道我可以用 @JacksonXmlRootElement
设置根标签,但是否可以将其设置为变量名。
@JacksonXmlRootElement(localName = 'ExistingName')
class MyPojo {
String commonVar1
String commonVar1
String commonVar1
}
您可以使用 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>
我最终找到 Get Jackson XMLMapper to set root element name in code 并使用
进行设置XmlMapper mapper = new XmlMapper();
.writer()
.withRootName(myFieldName)
.writeValueAsString(myPojo ));