简体   繁体   English

杰克逊中的多态反序列化将特定字段的值设置为null

[英]Polymorphic deserialization in jackson sets value null for specific fields

Problem statement 问题陈述
Is that the JSON which is to be deserialize into the below given POJO's is setting value of credentialType as null when i send the below JSON through postman 是当我通过邮递员发送以下JSON时要反序列化到以下给定POJO的JSON将credentialType的值设置为null

{
"credential": [
    {
        "@type": "mobile",
        "credentialName": "cred-2",
        "email": "s@s.com"
    },
    {
        "@type": "card",
        "credentialNumber": "1"
    }
]

} }

Expected outcome 预期结果
What i want to achieve is that with the above JSON the credential type should be set as either MOBILE for MobileCredentialDto or CARD for CardCredentialDto 我要实现的是,使用上述JSON,凭据类型应设置为MobileCredentialDto的MOBILE或CardCredentialDto的CARD

@Getter

public class SecureDto { 公共类SecureDto {

private  List<CredentialDto> credential;

@JsonCreator
public HandoutDto(@JsonProperty("credential") final List<CredentialDto> credential) {
    this.credential = Collections.unmodifiableList(credential);
}

} }

@Getter
public class SecureDto {

    private  List<CredentialDto> credential;

    @JsonCreator
    public HandoutDto(@JsonProperty("credential") final List<CredentialDto> credential) {
        this.credential = Collections.unmodifiableList(credential);
    }
}


@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
        @JsonSubTypes.Type(value = CardCredentialDto.class, name = "card"),
        @JsonSubTypes.Type(value = MobileCredentialDto.class, name = "mobile"),
})
@Getter
@Setter
public class CredentialDto {
    private CredentialType credentialType;

    @JsonCreator
    public CredentialDto(@JsonProperty("credentialType") final String credentialType) {
        this.credentialType = CredentialType.valueOf(credentialType);
    }

    public CredentialDto() {

    }

      public void setCredentialType(final CredentialType credentialType) {
        this.credentialType = CredentialType.MOBILE;
    }
}

@Getter
@Setter
public class MobileCredentialDto extends CredentialDto {
    private String credentialName;
    private String email;

    public MobileCredentialDto(final String credentialId,
                               final String state,
                               final String credentialNumber,
                               final String credentialName,
                               final String email) {
        super(credentialId, state, credentialNumber, CredentialType.MOBILE.name());
        this.credentialName = credentialName;
        this.email = email;
    }

    public MobileCredentialDto() {

    }

    public String getCredentialName() {
        return credentialName;
    }

    public String getEmail() {
        return email;
    }
}


@Getter
@Setter
public class CardCredentialDto extends CredentialDto {

    public CardCredentialDto(final String credentialId,
                             final String state,
                             final String credentialNumber) {
        super(credentialId, state, credentialNumber,CredentialType.CARD.name());
    }

    public CardCredentialDto() {

    }
}

public enum CredentialType {
    MOBILE("MOBILE"),
    CARD("CARD");

    private final String name;

    CredentialType(final String name) {
        this.name = name;
    }
}

I Found the answer. 我找到了答案。

what i did was set the visible = true in JsonTypeInfo. 我所做的是在JsonTypeInfo中设置visible = true。 In short by setting the visible = true allowed the jackson to do the following 简而言之,通过设置visible = true允许杰克逊执行以下操作

Note on visibility of type identifier: by default, deserialization (use during reading of JSON) of type identifier is completely handled by Jackson, and is not passed to deserializers. 关于类型标识符的可见性的注意事项:默认情况下,类型标识符的反序列化(在读取JSON时使用)完全由Jackson进行处理,并且不会传递给反序列化器。 However, if so desired, it is possible to define property visible = true in which case property will be passed as-is to deserializers (and set via setter or field) on deserialization. 但是,如果需要的话,可以定义属性visible = true,在这种情况下,属性将在反序列化时按原样传递给解串器(并通过setter或field进行设置)。

Refer the doc here for more understanding. 请参阅此处的文档以了解更多信息。 https://fasterxml.github.io/jackson-annotations/javadoc/2.4/com/fasterxml/jackson/annotation/JsonTypeInfo.html https://fasterxml.github.io/jackson-annotations/javadoc/2.4/com/fasterxml/jackson/annotation/JsonTypeInfo.html

Below is the code 下面是代码

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME , 
visible = true,
property = "credentialType")
@JsonSubTypes({
        @JsonSubTypes.Type(value = CardCredentialDto.class, name = "card"),
        @JsonSubTypes.Type(value = MobileCredentialDto.class, name = "mobile"),
})
@Getter
@Setter
public class CredentialDto {
   @JsonProperty(value = "credentialType")
    private CredentialType credentialType;

    @JsonCreator
    public CredentialDto(@JsonProperty("credentialType") final String credentialType) {
        this.credentialType = CredentialType.valueOf(credentialType);
    }

    public CredentialDto() {

    }

      public void setCredentialType(final CredentialType credentialType) {
        this.credentialType = CredentialType.MOBILE;
    }
}

and the json will look like this 和json看起来像这样

{
    "credential": [
        {
            "credentialType": "mobile",
            "credentialName": "cred-2",
            "email": "s@s.com"
        },
        {
            "credentialType": "card",
            "credentialNumber": "1"
        }
    ]
}

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

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