繁体   English   中英

使用Spring存储库时,@ JsonView失败并显示``IllegalStateException无法覆盖序列化器''

[英]@JsonView fails with 'IllegalStateException Can not override serializer' when using Spring repository

我们正在使用一些Spring(v4.1.3.RELEASE)存储库,最近开始使用@JsonView来过滤系统中其他Controller的一些响应数据。 今天,我们发现杰克逊由于未知原因(带有@JsonView批注标记的属性)而尝试并未能交换序列化程序。

调试导致我们进入BeanSerializerBase.resolve(..)=第#333-#337行,在该行进行分配,但随后失败,并出现异常'IllegalStateException无法覆盖序列化程序'。 代码中还参考了[JACKSON-364]。

删除所有JsonView批注将其固定为一种解决方法。

我们仍在尝试调试并确定其根本原因,但是任何提示在此都将不胜感激。

谢谢!

我们可以在源代码中看到

com.fasterxml.jackson.databind.ser.BeanPropertyWriter

    /**
     * Method called to assign value serializer for property
     * 
     * @since 2.0
     */
    public void assignSerializer(JsonSerializer<Object> ser)
    {
        // may need to disable check in future?
        if (_serializer != null && _serializer != ser) {
            throw new IllegalStateException("Can not override serializer");
        }
        _serializer = ser;
    }

因此,我们无法使用此writer类动态更改序列化程序。

为了隐藏这个问题,我们可以使用(例如)

    public class ExtendBeanPropertyWriter extends BeanPropertyWriter {

        // constructors

        @Override
        public BeanPropertyWriter unwrappingWriter(NameTransformer unwrapper) {
            return new ExtendUnwrappingBeanPropertyWriter(this, unwrapper);
        }

        @Override
        public void assignSerializer(JsonSerializer<Object> ser) {
            _serializer = ser;
        }

    }

我们必须记住UnwrappedBeanPropertyWriter

    public class ExtendUnwrappingBeanPropertyWriter extends UnwrappingBeanPropertyWriter {


        // constructors

        @Override
        public void assignSerializer(JsonSerializer<Object> ser) {
            _serializer = ser;
        }

    }

然后,我们可以扩展BeanSerializerModifier方法-changeProperties,以将writer的类更改为我们的实现,并避免该异常。

public class ExtendBeanSerializerModifier extends BeanSerializerModifier {

    private AnnotationIntrospector annotationIntrospector;

    // constructors

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {

        annotationIntrospector = null == config ? null : config.getAnnotationIntrospector();
        List<BeanPropertyWriter> result = new ArrayList<BeanPropertyWriter>();
        for (BeanPropertyWriter beanPropertyWriter : beanProperties) {
            BeanPropertyWriter bpw = beanPropertyWriter;
            // we can get views from bpw.getViews(); active view from config.getActiveView();
            // we also can use own annotations, for example - beanDesc.getBeanClass().getAnnotation(SomeClass.class);
            result.add(getExtendBPW(bpw));
        }
        return result;
    }

    public BeanPropertyWriter getExtendBPW(BeanPropertyWriter bpw) {
        BeanPropertyWriter writer = new ExtendBeanPropertyWriter(bpw);
        if (null != annotationIntrospector) {
            NameTransformer unwrapper = annotationIntrospector.findUnwrappingNameTransformer(bpw.getMember());
            if (null != unwrapper) {
                writer = writer.unwrappingWriter(unwrapper);
            }
        }
        return writer;
    }

}

甚至在那之后,您也可能会遇到JsonView问题。 您可能还必须添加自己的HttpMessageConverter和/或方法Interceptor(可以在Internet上找到示例)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM