jackjson-databind-2.9.3 笔记

问题

客户端请求:

{"skip":0,"take":10,"corpName":"","cityCode":{}}

服务器端接收参数

            @RequestBody query: ListQueryModel,
            corpName: String

调试

jackson-databind-2.9.3.jar!/com/fasterxml/jackson/databind/deser/BeanDeserializer.class

private final Object vanillaDeserialize(JsonParser p, DeserializationContext ctxt, JsonToken t) throws IOException {
        Object bean = this._valueInstantiator.createUsingDefault(ctxt);
        p.setCurrentValue(bean);
        if (p.hasTokenId(5)) {
            String propName = p.getCurrentName();

            do {
                p.nextToken();
                SettableBeanProperty prop = this._beanProperties.find(propName);
                if (prop != null) {
                    try {
                        prop.deserializeAndSet(p, ctxt, bean);
                    } catch (Exception var8) {
                        this.wrapAndThrow(var8, bean, propName, ctxt);
                    }
                } else {
                    this.handleUnknownVanilla(p, ctxt, bean, propName);
                }
            } while((propName = p.nextFieldName()) != null);
        }

        return bean;
    }

对比之前的版本:
jackson-databind-2.8.10-sources.jar!/com/fasterxml/jackson/databind/deser/BeanDeserializer.java

private final Object vanillaDeserialize(JsonParser p,
    		DeserializationContext ctxt, JsonToken t)
        throws IOException
    {
        final Object bean = _valueInstantiator.createUsingDefault(ctxt);
        // [databind#631]: Assign current value, to be accessible by custom serializers
        p.setCurrentValue(bean);
        if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) {
            String propName = p.getCurrentName();
            do {
                p.nextToken();
                SettableBeanProperty prop = _beanProperties.find(propName);

                if (prop != null) { // normal case
                    try {
                        prop.deserializeAndSet(p, ctxt, bean);
                    } catch (Exception e) {
                        wrapAndThrow(e, bean, propName, ctxt);
                    }
                    continue;
                }
                handleUnknownVanilla(p, ctxt, bean, propName);
            } while ((propName = p.nextFieldName()) != null);
        }
        return bean;
    }


    protected void handleUnknownVanilla(JsonParser p, DeserializationContext ctxt, Object bean, String propName)
        throws IOException
    {
        if (_ignorableProps != null && _ignorableProps.contains(propName)) {
            handleIgnoredProperty(p, ctxt, bean, propName);
        } else if (_anySetter != null) {
            try {
               // should we consider return type of any setter?
                _anySetter.deserializeAndSet(p, ctxt, bean, propName);
            } catch (Exception e) {
                wrapAndThrow(e, bean, propName, ctxt);
            }
        } else {
            // Unknown: let's call handler method
            handleUnknownProperty(p, ctxt, bean, propName);         
        }
    }


    protected void handleUnknownProperty(JsonParser p, DeserializationContext ctxt,
            Object beanOrClass, String propName)
        throws IOException
    {
        if (_ignoreAllUnknown) {
            p.skipChildren();
            return;
        }
        if (_ignorableProps != null && _ignorableProps.contains(propName)) {
            handleIgnoredProperty(p, ctxt, beanOrClass, propName);
        }
        // Otherwise use default handling (call handler(s); if not
        // handled, throw exception or skip depending on settings)
        super.handleUnknownProperty(p, ctxt, beanOrClass, propName);
    }

jackson-databind-2.8.10-sources.jar!/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java

    protected void handleUnknownProperty(JsonParser p, DeserializationContext ctxt, Object instanceOrClass, String propName)
        throws IOException
    {
        if (instanceOrClass == null) {
            instanceOrClass = handledType();
        }
        // Maybe we have configured handler(s) to take care of it?
        if (ctxt.handleUnknownProperty(p, this, instanceOrClass, propName)) {
            return;
        }
        /* But if we do get this far, need to skip whatever value we
         * are pointing to now (although handler is likely to have done that already)
         */
        p.skipChildren();
    }

对比发现

2.8.10 会忽略掉客户端请求中多余的属性。
2.9.3 会报错。
2.9.5 的逻辑 又和 2.8.10 一样。

这就是坑。

posted @ 2018-05-20 10:45  NewSea  阅读(889)  评论(0编辑  收藏  举报