简体   繁体   English

扩展杰克逊自定义序列化器

[英]Extending a jackson custom serializer

Given MyClass2 extends MyClass1 and just adds two more properties to MyClass1, I wrote two Jackson custom serializers for the two classes like so: 给定MyClass2扩展了MyClass1并仅向MyClass1添加了两个属性,我为两个类编写了两个Jackson自定义序列化器,如下所示:

public class MyClass1Serializer extends JsonSerializer<MyClass1> {

    @Override
    public void serialize(MyClass1 myClass1, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("ApplicationName", myClass1.getApplicationName());
        jsonGenerator.writeStringField("UserName", myClass1.getUserName());
    }       
}

and

public class MyClass2Serializer extends JsonSerializer<MyClass2> {

    @Override
    public void serialize(MyClass2 myClass2, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("ApplicationName", myClass2.getApplicationName());       
        jsonGenerator.writeStringField("ErrorMessage", myClass2.getErrorMessage());
        jsonGenerator.writeStringField("ResultCode", myClass2.getResultCode());
        jsonGenerator.writeStringField("UserName", myClass2.getUserName());
    }       
}

Which works fine, and gives me the following output: 哪个工作正常,并提供以下输出:

{"ApplicationName":"FakeApp","UserName":"Joe the Schmoe"} {“ ApplicationName”:“ FakeApp”,“ UserName”:“ Joe the Schmoe”}

{"ApplicationName":"AnotherApp","ErrorMessage":"Uh oh!","ResultCode":"Errrrm, not good...","UserName":"John Doe"} {“ ApplicationName”:“ AnotherApp”,“ ErrorMessage”:“呃哦!”,“ ResultCode”:“ Errrrm,不好...”,“ UserName”:“ John Doe”}

Well, to me, it looks like there is code duplication in the two serialize methods, and could I subclass the second serializer from the first? 好吧,对我来说,这两个序列化方法似乎有代码重复,我可以从第一个序列化第二个序列化器吗? Hmmmm... Hmmmm ...

Ummm, well, I tried this: 嗯,好吧,我尝试了这个:

public class MyClass1Serializer<T extends MyClass1> extends JsonSerializer<MyClass1> {

    @Override
    public void serialize(MyClass1 myClass1, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("ApplicationName", myClass1.getApplicationName());
        jsonGenerator.writeStringField("UserName", myClass1.getUserName());
    }       
}

and

public class MyClass2Serializer extends MyClass1Serializer<MyClass2> {

    public void serialize(MyClass2 myClass2, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

        super.serialize(myClass2, jsonGenerator, serializerProvider);
        jsonGenerator.writeStringField("ErrorMessage", myClass2.getErrorMessage());
        jsonGenerator.writeStringField("ResultCode", myClass2.getResultCode());
    }       
}

Which compiles and runs, but gives me this output: 哪个可以编译并运行,但是给我以下输出:

{"ApplicationName":"FakeApp","UserName":"Joe the Schmoe"} {“ ApplicationName”:“ FakeApp”,“ UserName”:“ Joe the Schmoe”}

{"ApplicationName":"AnotherApp","UserName":"John Doe"} {“ ApplicationName”:“ AnotherApp”,“ UserName”:“ John Doe”}

Pretty clear to me that MyClass2Serializer is now completely ignored and Jackson finds the MyClass1Serializer and uses it for MyClass2. 我很清楚MyClass2Serializer现在已被完全忽略,Jackson找到了MyClass1Serializer并将其用于MyClass2。 (Since it doesn't directly subclass JsonSerializer?) (因为它没有直接子类化JsonSerializer?)

Granted for this simple situation, no big deal, but my real-world class structure at work could really benefit by "chaining" custom serializers together instead of starting each one from scratch. 允许这种简单的情况,没什么大不了的,但是我在工作中的实际类结构可以通过将自定义序列化器“链接”在一起而真正受益,而不必从头开始。

Just in case it matters, I tell Jackson which serializer to use for which class using an annotation on the class: 以防万一,我通过类的批注告诉Jackson用于哪个类的序列化器:

@JsonSerialize(using=MyClass1Serializer.class)
public class MyClass1 {

Possible future question: Assuming subclassing a custom serializer is even possible, can subclassing a custom deserializer work as well? 将来可能出现的问题:假设甚至可以将自定义序列化器子类化,也可以将自定义解串器子类化吗? A pointer to some sample code or tutorial would be awesome! 指向一些示例代码或教程的指针真棒!

funny thing: I tried to replicate the problem, but it seems to work: 有趣的事情:我试图重现该问题,但似乎可行:

import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.*;

public class Test
{
    public static void main(String[] args) {
        MyClass1 myc1 = new MyClass1("app1", "user1");
        MyClass1 myc2 = new MyClass2("app2", "user2", "err2", "rc2");

        try {
            System.out.println(new ObjectMapper().writeValueAsString(myc1));
            System.out.println(new ObjectMapper().writeValueAsString(myc2));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @JsonSerialize(using = MyClass1Serializer.class)
    public static class MyClass1 {
        protected String applicationName;
        protected String userName;

        public MyClass1() {}

        public MyClass1(String applicationName, String userName) {
            this.applicationName = applicationName;
            this.userName = userName;
        }

        public String getApplicationName() { return applicationName; }
        public String getUserName()        { return userName; }
    }

    @JsonSerialize(using = MyClass2Serializer.class)
    public static class MyClass2 extends MyClass1 {
        protected String errorMessage;
        protected String resultCode;

        public MyClass2() {}

        public MyClass2(String applicationName, String userName, String errorMessage, String resultCode) {
            super(applicationName, userName);
            this.errorMessage = errorMessage;
            this.resultCode = resultCode;
        }

        public String getErrorMessage() { return errorMessage; }
        public String getResultCode()   { return resultCode; }
    }

    public static class MyClass1Serializer<T extends MyClass1> extends JsonSerializer<T> {
        @Override
        public void serialize(MyClass1 myClass1, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                throws IOException
        {
            jsonGenerator.writeStartObject();
            jsonGenerator.writeStringField("ApplicationName", myClass1.getApplicationName());
            jsonGenerator.writeStringField("UserName", myClass1.getUserName());
            //jsonGenerator.writeEndObject();
        }
    }

    public static class MyClass2Serializer extends MyClass1Serializer<MyClass2> {
        @Override
        public void serialize(MyClass2 myClass2, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                throws IOException
        {
            super.serialize(myClass2, jsonGenerator, serializerProvider);
            jsonGenerator.writeStringField("ErrorMessage", myClass2.getErrorMessage());
            jsonGenerator.writeStringField("ResultCode", myClass2.getResultCode());
            //jsonGenerator.writeEndObject();
        }
    }
}

Output: 输出:

{"ApplicationName":"app1","UserName":"user1"}
{"ApplicationName":"app2","UserName":"user2","ErrorMessage":"err2","ResultCode":"rc2"}

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

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