我们正在使用一些 Spring (v4.1.3.RELEASE) 存储库,最近开始使用 @JsonView 来过滤系统中其他 Controller 的一些响应数据。 今天我们发现 Jackson 尝试交换序列化器,但由于使用 @JsonView 注释标记的属性的未知原因而失败。
调试使我们到达 BeanSerializerBase.resolve(..) = 行#333-#337,其中进行了分配,但稍后失败并出现异常“IllegalStateException Can not override serializer”。代码中还引用了 [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;
}
因此我们无法使用此编写器类动态更改序列化器。
为了隐藏这个问题,我们可以使用(例如)
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 和/或方法拦截器(您可以在互联网上找到示例)。
关于java - 使用 Spring 存储库时 @JsonView 失败并显示 'IllegalStateException Can not override serializer',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31456112/