我目前正在处理一个项目,该项目处理的元素(由于遗留原因)必须具有表示其类型的标签名称.
I'm currently working on a project that deals with elements that (for legacy reasons) must have a tag name that represents their type.
基本上我有这个:
@JsonRootName("node") class NodeDocument { private String type; }输出类似:
<node type="someType"></node>但是可以预期的是:
<someType></someType>@JsonRootName似乎无法在方法或属性上使用.
@JsonRootName doesn't seem to be usable on a method or attribute.
即使有SerializationConfig.withRooName()或自定义序列化程序,我似乎也找不到一种用存储在对象本身中的动态值定义根名称的方法.
Even though there is SerializationConfig.withRooName() or custom serializers, I can't seem to find a way to define the root name with a dynamic value stored in the object itself.
推荐答案我假定NodeDocument包含多个属性.在这种情况下,您需要将自定义序列化程序与BeanSerializerModifier一起实现,以允许您序列化所有属性.下面的代码显示了完整的解决方案:
I assume NodeDocument contains more than just one property. In that case you need to implement custom serialiser together with BeanSerializerModifier which allow you to serialise all properties. Below code shows complete solution:
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; import com.fasterxml.jackson.databind.util.NameTransformer; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; import javax.xml.namespace.QName; import java.io.IOException; import java.util.Objects; public class XmlJacksonApp { public static void main(String... args) throws Exception { SimpleModule dynamicRootNameModule = new SimpleModule(); dynamicRootNameModule.setSerializerModifier(new DynamicRootNameBeanSerializerModifier()); XmlMapper mapper = XmlMapper.xmlBuilder() .enable(SerializationFeature.INDENT_OUTPUT) .addModule(dynamicRootNameModule) .build(); NodeDocument element = new NodeDocument(); element.setId(123); element.setName("Rick and Morty.doc"); element.setType("sitcom"); mapper.writeValue(System.out, element); } } class DynamicRootNameBeanSerializerModifier extends BeanSerializerModifier { @Override public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) { if (beanDesc.getBeanClass() == NodeDocument.class) { return new NodeDocumentJsonSerializer((JsonSerializer<NodeDocument>) serializer); } return super.modifySerializer(config, beanDesc, serializer); } } class NodeDocumentJsonSerializer extends JsonSerializer<NodeDocument> { private final JsonSerializer<NodeDocument> serializer; NodeDocumentJsonSerializer(JsonSerializer<NodeDocument> serializer) { this.serializer = Objects.requireNonNull(serializer); } @Override public void serialize(NodeDocument value, JsonGenerator gen, SerializerProvider serializers) throws IOException { ToXmlGenerator xmlGen = (ToXmlGenerator) gen; writeDynamicRootName(value.getType(), xmlGen); serializeProperties(value, gen, serializers); writeEndObject(xmlGen); } private void writeDynamicRootName(String rootName, ToXmlGenerator xmlGen) throws IOException { xmlGen.setNextName(new QName("", rootName)); xmlGen.writeStartObject(); } private void serializeProperties(NodeDocument value, JsonGenerator gen, SerializerProvider serializers) throws IOException { serializer.unwrappingSerializer(NameTransformer.NOP).serialize(value, gen, serializers); } private void writeEndObject(ToXmlGenerator xmlGen) throws IOException { xmlGen.writeEndObject(); } } class NodeDocument { @JsonIgnore private String type; private int id; private String name; // getters, setters }上面的代码显示:
<sitcom> <id>123</id> <name>Rick and Morty.doc</name> </sitcom>更多推荐
杰克逊的动态根元素
发布评论