【问题标题】:Jackson: using builder with nondefault constructor杰克逊:使用带有非默认构造函数的构建器
【发布时间】:2014-03-24 14:50:51
【问题描述】:

我有以下课程:

@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 映射器对其进行序列化时,我得到以下 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)

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

【问题讨论】:

    标签: xml jackson deserialization builder


    【解决方案1】:

    毕竟我成功编写了这个构建器:

    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 的值不是空的,它实际上可以是除空字符串之外的任何值。我不相信这是有史以来最好的解决方案,但它确实有效。但我不会接受我自己的答案,因为可能有更好的解决方案。

    【讨论】:

    • 对于“@JsonProperty”,您应该填写属性的名称,在您的情况下应该是“transactionType”。如果您将“@JsonProperty”留空,如果您的 Builder 构造函数中有多个参数,则会引发 Json 异常。
    猜你喜欢
    • 2012-08-04
    • 2019-01-08
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 2015-01-23
    • 2019-03-29
    • 2015-07-16
    • 2010-10-30
    相关资源
    最近更新 更多