在jackson mixins中同时使用@JsonIgnore和@JsonProperty的问题

时间:2015-06-22 12:01:06

标签: java json annotations jackson

我有一个用例在jackson mixin中同时使用@JsonIgnore@JsonProperty

这是我的mixin:

public abstract class MessageMixin {
    @JsonIgnore
    Member sender;

    @JsonIgnore
    Member recipient;

    @JsonProperty("senderId")
    Long getSenderId() {
        return sender.getId();
    }

    @JsonProperty("recipientId")
    Long getRecipientId() {
        return recipient.getId();
    }

    @JsonProperty("senderFirstName")
    String getSenderFirstName() {
        return sender.getFirstName();
    }

    @JsonProperty("recipientFirstName")
    String getRecipientFirstName() {
        return recipient.getFirstName();
    }
}

senderrecipient字段已正确忽略,但未添加任何@JsonProperty字段。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

混合输入对于将Jackson配置应用于类而不修改目标类的源代码非常有用。混合可以被认为是一个配置层,位于杰克逊将在去/序列化期间查看指令的类之上。 Mix-ins的一个好处是它们可以将杰克逊特定的配置与项目代码分离,从而允许您撕掉杰克逊并使用新的框架,而无需修改所有的VO。话虽如此,为了实例化而扩展Mix-in会很奇怪。我想你会想要在你的Mix-in中避免像sender.getFirstName()这样的逻辑,并允许基类填充值。例如,对于您提供的混合,我希望我的基类具有公共senderrecipient成员,并且您的混合是完全抽象的。

如果Message是已存在的类

假设像这样的基类:

public class Message {
    public Member sender;
    public Member recipient;

    public Message(Member sender, Member recipient) {
        this.sender = sender;
        this.recipient = recipient;
    }

    public Long getSenderId() {
        return sender.getId();
    }

    public Long getRecipientId() {
        return recipient.getId();
    }

    public String getSenderFirstName() {
        return sender.getFirstName();
    }

    public String getRecipientFirstName() {
        return recipient.getFirstName();
    }
}

如果没有混合,这个类会产生:

{
    "sender": {
        "id": 883,
        "firstName": "Bob"
    },
    "recipient": {
        "id": 3993,
        "firstName": "Jilly"
    },
    "senderId": 883, 
    "recipientId": 3993, 
    "senderFirstName": "Bob", 
    "recipientFirstName": "Jilly"
}

要介绍混合输入并忽略senderrecipient而不修改Message,必须在ObjectMapper注册混合输入。

Mix-in可能如下所示:

public abstract class MessageMixin {
    @JsonIgnore
    Member sender;

    @JsonIgnore
    Member recipient;

    @JsonProperty("senderId")
    abstract Long getSenderId();

    @JsonProperty("recipientId")
    abstract Long getRecipientId();

    @JsonProperty("senderFirstName")
    abstract String getSenderFirstName();

    @JsonProperty("recipientFirstName")
    abstract String getRecipientFirstName();
}

ObjectMapper配置如下:

ObjectMapper om = new ObjectMapper()
        .addMixIn(Message.class, MessageMixin.class);

它将输出以下JSON:

{
    "senderId": 883,
    "senderFirstName": "Bob",
    "recipientFirstName": "Jilly",
    "recipientId": 3993
}

如果Message不存在

如果不存在Message基类,那么最好创建一个简单的POJO来完成“消息”表示。像这样的东西可以很好地用于序列化和反序列化。

public class MessagePojo {
    private final Member sender;
    private final Member recipient;

    @JsonCreator
    public MessagePojo(@JsonProperty("sender") Member sender,
                       @JsonProperty("recipient") Member recipient) {
        this.sender = sender;
        this.recipient = recipient;
    }

    @JsonProperty("senderId")
    public Long getSenderId() {
        return sender.getId();
    }

    @JsonProperty("recipientId")
    public Long getRecipientId() {
        return recipient.getId();
    }

    @JsonProperty("senderFirstName")
    public String getSenderFirstName() {
        return sender.getFirstName();
    }

    @JsonProperty("recipientFirstName")
    public String getRecipientFirstName() {
        return recipient.getFirstName();
    }
}