[英]@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.