简体   繁体   English

Jackson 多态序列化生成不正确的 class 名称

[英]Jackson polymorphic serialization generates an incorrect class name

When I use Jackson polymorphic serialization, it generates a JSON object with an incorrect fully qualified class name.当我使用 Jackson 多态序列化时,它会生成 JSON object 以及不正确的完全限定名称 class。

The code below serializes an XMLGregorianCalendar.下面的代码序列化了一个 XMLGregorianCalendar。 The output is: output 是:

["java.util.GregorianCalendar",-3600000]

I expected the following:我期望以下内容:

["javax.xml.datatype.XMLGregorianCalendar",-3600000]

Why does it output java.util.GregorianCalendar?为什么它是 output java.util.GregorianCalendar?

Or more importantly: How do I fix this?或者更重要的是:我该如何解决这个问题?

Code example:代码示例:

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.io.ByteArrayOutputStream;

public class JacksonGregorianProblem {

    public static void main(String[] args) throws java.io.IOException, DatatypeConfigurationException {

        XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar();
        ObjectMapper mapper = new ObjectMapper();
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        mapper.writeValue(byteArrayOutputStream, xmlGregorianCalendar);

        System.out.println(byteArrayOutputStream);
    }
}

To get the expected behavior I have implemented a custom XMLGregorianCalendar serializer. 为了获得预期的行为,我实现了一个自定义的XMLGregorianCalendar序列化程序。 This class takes care of the serialization of the XLMGregorianCalendar and now the output is exactly what I expect. 这个类负责XLMGregorianCalendar的序列化,现在输出正是我所期望的。 :-) :-)

class XMLGregorianCalendarSerializer extends StdSerializer<XMLGregorianCalendar> {

    public XMLGregorianCalendarSerializer() {
        this(null);
    }

    public XMLGregorianCalendarSerializer(Class<XMLGregorianCalendar> t) {
        super(t);
    }

    @Override
    public void serialize(XMLGregorianCalendar value, JsonGenerator gen, SerializerProvider provider)
        throws IOException
    {
        gen.writeNumber(value.toGregorianCalendar().getTimeInMillis());
    }

    @Override
    public void serializeWithType(XMLGregorianCalendar value, JsonGenerator gen, SerializerProvider provider,
        TypeSerializer typeSerializer) throws IOException
    {
        gen.writeStartArray();
        gen.writeString("javax.xml.datatype.XMLGregorianCalendar");
        serialize(value, gen, provider); // call your customized serialize method
        gen.writeEndArray();
    }
}

You can add this serializer to the object mapper with the code below. 您可以使用以下代码将此序列化程序添加到对象映射器。 It can be pasted in the code example in the question. 它可以粘贴在问题的代码示例中。

    SimpleModule module = new SimpleModule();
    module.addSerializer(XMLGregorianCalendar.class, new XMLGregorianCalendarSerializer());
    mapper.registerModule(module);

XMLGregorian calendar suppose to handle serialization and deserialization alone. XML 公历假设单独处理序列化和反序列化。 Therefore I prefer to use the following serializer and deserializer:因此,我更喜欢使用以下序列化器和反序列化器:

private class XMLCalendarDeserializer extends StdDeserializer<XMLGregorianCalendar> {

        private DatatypeFactory factory = DatatypeFactory.newDefaultInstance();
        
        public XMLCalendarDeserializer() {
            super(XMLGregorianCalendar.class);
        }

        
        
        @Override
        public XMLGregorianCalendar deserialize(JsonParser parser, DeserializationContext ctx) throws IOException, JsonProcessingException {
            if (parser.hasToken(JsonToken.VALUE_STRING)) {
                return factory.newXMLGregorianCalendar(parser.getText());
            } else {
                throw new JsonParseException(parser, "not string token");
            }
        }
        
    }
    
    private class XMLCalendarSerializer extends StdSerializer<XMLGregorianCalendar> {

        public XMLCalendarSerializer() {
            super(XMLGregorianCalendar.class);
        }
        
        @Override
        public void serialize(XMLGregorianCalendar val, JsonGenerator gen, SerializerProvider ser) throws IOException {
            gen.writeString(val.toXMLFormat());
        }
        
    }

` `

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM