java - 在这种情况下,Jackson 在使用 ObjectMapper.readTree 反序列化 JSON 时会创建 ShortNode?

标签 java json jackson

我有一些代码通过 Jackson 的 ObjectMapperInputStream 反序列化 JSON(基本上,就像 new ObjectMapper().readTree(...). 我发现它为整数创建 IntNodeLongNode(取决于数字有多大),但我从未见过 ShortNode 。我需要知道它们何时创建(如果创建的话),因为我有一些依赖于 NumericNode.numberValue() 返回类型的棘手逻辑。 我在 jackson 的文档中没有找到任何内容,而且 jackson 的代码对我来说看起来不是很清楚。

最佳答案

com.fasterxml.jackson.core.JsonToken枚举包含 VALUE_NUMBER_INT如下documentation :

VALUE_NUMBER_INT is returned when an integer numeric token is encountered in value context: that is, a number that does not have floating point or exponent marker in it (consists only of an optional sign, followed by one or more digits)

还有VALUE_NUMBER_FLOAT用于 float 的标记。 另请查看com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer#_fromInt您可以找到here的方法.

protected final JsonNode _fromInt(JsonParser p, DeserializationContext ctxt,
        JsonNodeFactory nodeFactory) throws IOException
{
    JsonParser.NumberType nt;
    int feats = ctxt.getDeserializationFeatures();
    if ((feats & F_MASK_INT_COERCIONS) != 0) {
        if (DeserializationFeature.USE_BIG_INTEGER_FOR_INTS.enabledIn(feats)) {
            nt = JsonParser.NumberType.BIG_INTEGER;
        } else if (DeserializationFeature.USE_LONG_FOR_INTS.enabledIn(feats)) {
            nt = JsonParser.NumberType.LONG;
        } else {
            nt = p.getNumberType();
        }
    } else {
        nt = p.getNumberType();
    }
    if (nt == JsonParser.NumberType.INT) {
        return nodeFactory.numberNode(p.getIntValue());
    }
    if (nt == JsonParser.NumberType.LONG) {
        return nodeFactory.numberNode(p.getLongValue());
    }
    return nodeFactory.numberNode(p.getBigIntegerValue());
}

您还必须看看 com.fasterxml.jackson.core.base.ParserBase#_parseNumericValue您可以找到here的方法

/**
 * Method that will parse actual numeric value out of a syntactically
 * valid number value. Type it will parse into depends on whether
 * it is a floating point number, as well as its magnitude: smallest
 * legal type (of ones available) is used for efficiency.
 *
 * @param expType Numeric type that we will immediately need, if any;
 *   mostly necessary to optimize handling of floating point numbers
 */
protected void _parseNumericValue(int expType) throws IOException
{
    // Int or float?
    if (_currToken == JsonToken.VALUE_NUMBER_INT) {
        int len = _intLength;
        // First: optimization for simple int
        if (len <= 9) { 
            int i = _textBuffer.contentsAsInt(_numberNegative);
            _numberInt = i;
            _numTypesValid = NR_INT;
            return;
        }
        if (len <= 18) { // definitely fits AND is easy to parse using 2 int parse calls
            long l = _textBuffer.contentsAsLong(_numberNegative);
            // Might still fit in int, need to check
            if (len == 10) {
                if (_numberNegative) {
                    if (l >= MIN_INT_L) {
                        _numberInt = (int) l;
                        _numTypesValid = NR_INT;
                        return;
                    }
                } else {
                    if (l <= MAX_INT_L) {
                        _numberInt = (int) l;
                        _numTypesValid = NR_INT;
                        return;
                    }
                }
            }
            _numberLong = l;
            _numTypesValid = NR_LONG;
            return;
        }
        _parseSlowInt(expType);
        return;
    }
    if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) {
        _parseSlowFloat(expType);
        return;
    }
    _reportError("Current token (%s) not numeric, can not use numeric value accessors", _currToken);
}

如您所见,没有 shortShort反序列化期间的类型。您应该避免在外部库创建的值类型上创建逻辑。在这种情况下不可能强制使用Short .

编辑
当然这是不可能的,因为 JSON规范不支持这一点。请查看以下链接了解更多详细信息:

关于java - 在这种情况下,Jackson 在使用 ObjectMapper.readTree 反序列化 JSON 时会创建 ShortNode?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50193314/

相关文章:

java - 将 Realm 与 Gson 一起使用

java - Jackson 基于另一个字段的字段序列化

java - 如何使用 Jackson 解析嵌套的 JSON(无论是递归还是迭代)?

java - 在 Selenium Webdriver 中循环运行 Java 代码

Java JTable特定行和列值+另一个整数

java - 创建接收多态输入的方法

java - 从 java web 应用程序启动很长的后台进程的最佳方法是什么?

php - 如何在 PHP 中从查询创建 JSON

android - 如何在微调器中获取 json 响应?

java - 如何使用 JSON 动态创建 POJO?