杰克逊:使用非默认构造函数的构建器

时间:2014-03-24 14:50:52

标签: xml jackson deserialization builder

我有以下课程:     

@JsonDeserialize(builder = Transaction.Builder.class)
public final class Transaction {

    @JacksonXmlText
    private final TransactionType transactionType;
    @JacksonXmlProperty(isAttribute = true)
    private final boolean transactionAllowed;

    private Transaction(Builder builder) {
        transactionType = builder.transactionType;
        transactionAllowed = builder.transactionAllowed;
    }

    public static final class Builder {
        private final TransactionType transactionType;
        private boolean transactionAllowed;

        public Builder(TransactionType transactionType) {
            this.transactionType = transactionType;
        }

        public Builder withTransactionAllowed() {
            transactionAllowed = true;
            return this;
        }

        public Transaction build() {
            return new Transaction(this);
        }
    }
}

TransactionType是一个简单的枚举:     

public enum TransactionType {
    PU,
    CV;
}

当我创建一个新的Transaction实例并使用Jackson mapper序列化时,我得到以下xml:

<transaction transactionAllowed="true">PU</transaction>

问题是我无法反序列化它。我得到以下异常:

com.fasterxml.jackson.databind.JsonMappingException:
No suitable constructor found for type [simple type, class Transaction$Builder]

如果我将@JsonCreator放在Builder构造函数上,如下所示:     

@JsonCreator
public Builder(TransactionType transactionType) {
    this.transactionType = transactionType;
}

我得到以下异常:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct
instance of Transaction from String value 'transactionAllowed': value not one of
declared Enum instance names: [PU, CV]

如果我然后将@JsonProperty放在构造函数参数上,如下所示:     

@JsonCreator
public Builder(@JsonProperty TransactionType transactionType) {
    this.transactionType = transactionType;
}

我收到另一个错误:

com.fasterxml.jackson.databind.JsonMappingException: Could not find creator
property with name '' (in class Transaction$Builder)

任何想法如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

毕竟我写了这个构建器的工作:     

public static final class Builder {
    @JacksonXmlText
    private final TransactionType transactionType;
    private boolean transactionAllowed;

    @JsonCreator
    public Builder(@JsonProperty(" ") TransactionType transactionType) {
        this.transactionType = transactionType;
    }

    public Builder withTransactionAllowed() {
        transactionAllowed = true;
        return this;
    }

    public Transaction build() {
        return new Transaction(this);
    }
}

请注意,@ JsonProperty的值不为空,它实际上可以是除空字符串之外的任何值。我不相信这是有史以来最好的解决方案,但它确实有效。然而,由于可能有更好的解决方案,我不会接受我自己的答案。