【问题标题】:How do I force Jackson to use an Object's Setters?如何强制杰克逊使用对象的设置器?
【发布时间】:2017-12-19 21:28:53
【问题描述】:

鉴于我有以下 JSON 文件:

{
    "cleanup": false,
    "clearCache": false
}

还有以下 bean:

import org.apache.commons.lang3.Validate;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Config implements IHoldConfiguration {

    public static final boolean DEFAULT_CLEANUP = false;
    public static final boolean DEFAULT_CLEAR_CACHE = false;
    public static final int DEFAULT_CONCURRENCY = 1;

    @JsonProperty(value = "cleanup", required = false, defaultValue = "false")
    private Boolean cleanup;

    @JsonProperty(value = "clearCache", required = false, defaultValue = "false")
    private Boolean clearCache;

    @JsonProperty(value = "concurrency", required = false, defaultValue = "1")
    private Integer concurrency;

    public boolean isCleanup() {
        return this.cleanup.booleanValue();
    }

    public void setCleanup(final Boolean cleanup) {
        this.cleanup = cleanup != null ? cleanup : DEFAULT_CLEANUP;
    }

    public boolean isClearCache() {
        return this.clearCache.booleanValue();
    }

    public void setClearCache(final Boolean clearCache) {
        this.clearCache = clearCache != null ? clearCache : DEFAULT_CLEAR_CACHE;
    }

    public int getConcurrency() {
        return this.concurrency.intValue();
    }

    public void setConcurrency(Integer concurrency) {

        if (concurrency == null) {
            concurrency = DEFAULT_CONCURRENCY;
        } else {
            Validate.inclusiveBetween(1, Integer.MAX_VALUE, concurrency,
                    String.format("concurrency must be in range [1, %s]", Integer.MAX_VALUE));
        }

        this.concurrency = concurrency;
    }
}

如何强制 Jackson 2.9.2 使用我的 concurrency setter?目前,当从 JSON 反序列化为 bean 时,使用 new ObjectMapper().readValue(inputStream, Config.class)concurrency 设置为 null

我认为 Jackson 使用 bean 中的 setter(如果提供)来设置属性。在看到反序列化的结果和调试后,我发现这不是真的。由于JsonPropertydefaultValue 属性仅用于文档,我想我可以在设置器中添加默认值设置,但显然这不起作用。我怎样才能做到这一点?

【问题讨论】:

    标签: java jackson


    【解决方案1】:

    问题在于,由于未在您的 json 字符串中声明并发,因此未调用 setter。如果你有

    {
        cleanup: false,
        clearCache: false,
        concurrency: null
    }
    

    然后将使用 null 参数调用 setter,并设置默认值。

    要在不调整 json 字符串的情况下获得默认值,您可以做几件事。首先,您可以在声明变量时简单地设置变量的默认值:

    public class Config implements IHoldConfiguration {
        ...
        public static final int DEFAULT_CONCURRENCY = 1;
    
        ...
        private Integer concurrency = Integer.valueOf(DEFAULT_CONCURRENCY);
    

    现在,Jackson 不尝试设置并发并不重要,因为它已经用正确的值构造了。或者,您可以强制 Jackson 使用构造函数,它将传递所有值,即使是那些不在 json 字符串中的值。

    例如,您可以添加如下构造函数:

    @JsonCreator
    public Config (@JsonProperty("cleanup") Boolean cleanup,
                   @JsonProperty("clearCache") Boolean clearCache,
                   @JsonProperty("concurrency") Integer concurrency) {
        ....
    

    然后把你的逻辑放在那里。

    【讨论】:

      【解决方案2】:

      你不能强迫它被调用,因为没有任何东西可以调用它。

      设置默认值的常用方法是直接为声明中的字段赋值,例如:

      private Integer concurrency = Integer.valueOf(1);
      

      或在默认构造函数中执行此操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多