我如何强迫杰克逊使用对象的定位器?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我如何强迫杰克逊使用对象的定位器?相关的知识,希望对你有一定的参考价值。

鉴于我有以下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;
    }
}

我如何强迫杰克逊2.9.2使用我的concurrency二传手?目前,当从JSON反序列化为bean时,使用new ObjectMapper().readValue(inputStream, Config.class)concurrency设置为null

我认为杰克逊在豆子中使用了固定器(如果提供的话)来设置属性。在看到反序列化的结果和调试之后,我发现这不是真的。由于defaultValueJsonProperty属性仅用于文档,我认为我可以在setter中添加默认值设置,但显然这不起作用。我怎么能做到这一点?

答案

问题是,由于未在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使用构造函数,它将传递所有值,即使是那些不在json字符串中的值。

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

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

把你的逻辑放在那里。

另一答案

你不能强迫它被调用,因为没有什么可以调用它。

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

private Integer concurrency = Integer.valueOf(1);

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

以上是关于我如何强迫杰克逊使用对象的定位器?的主要内容,如果未能解决你的问题,请参考以下文章

使用杰克逊创建一个 json 对象

如何使用杰克逊制作自定义反序列化器将数字(即部门 ID)转换为部门对象?

杰克逊将对象序列化为字符串

我如何告诉杰克逊忽略我无法控制源代码的属性?

如何动态忽略杰克逊序列化的属性

如何使用jackson序列化通用对象