簡體   English   中英

傑克遜中的多態反序列化將特定字段的值設置為null

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

問題陳述
是當我通過郵遞員發送以下JSON時要反序列化到以下給定POJO的JSON將credentialType的值設置為null

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

}

預期結果
我要實現的是,使用上述JSON,憑據類型應設置為MobileCredentialDto的MOBILE或CardCredentialDto的CARD

@Getter

公共類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;
    }
}

我找到了答案。

我所做的是在JsonTypeInfo中設置visible = true。 簡而言之,通過設置visible = true允許傑克遜執行以下操作

關於類型標識符的可見性的注意事項:默認情況下,類型標識符的反序列化(在讀取JSON時使用)完全由Jackson進行處理,並且不會傳遞給反序列化器。 但是,如果需要的話,可以定義屬性visible = true,在這種情況下,屬性將在反序列化時按原樣傳遞給解串器(並通過setter或field進行設置)。

請參閱此處的文檔以了解更多信息。 https://fasterxml.github.io/jackson-annotations/javadoc/2.4/com/fasterxml/jackson/annotation/JsonTypeInfo.html

下面是代碼

@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;
    }
}

和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