@JsonFilter 抛出“JsonMappingException:无法解析 BeanPropertyFilter”
是否可以有选择地确定何时在运行时使用 @JsonFilter 注释?
当我不提供过滤器时,我收到 JsonMappingException 异常(见下文)。
背景:
我从最近的StackOverflow 帖子 说我可以使用 @JsonFilter 来动态过滤要序列化的 bean 属性。这很好用。将 @JsonFilter("apiFilter")
添加到我的域类并在我的 jax-rs 服务中添加此代码(使用 CXF 实现)后,我能够动态过滤由我的 RESTful API:
// shortened for brevity
FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.filterOutAllExcept(filterProperties));
return mapper.filteredWriter(filters).writeValueAsString(user);
问题是有不同的服务调用,我根本不想应用过滤器。在这些情况下,我想返回整个域类而不过滤任何属性。在我只是尝试返回域类的情况下,我收到如下异常:
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not resolve BeanPropertyFilter with id 'apiFilter'; no FilterProvider configured
at org.codehaus.jackson.map.ser.BeanSerializer.findFilter(BeanSerializer.java:252)
at org.codehaus.jackson.map.ser.BeanSerializer.serializeFieldsFiltered(BeanSerializer.java:216)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:140)
Is it possible to selectively determine when the @JsonFilter annotation gets used at runtime?
I'm getting JsonMappingException exception (see below) when I don't provide the filter.
Background:
I learned from a recent StackOverflow post that I can use @JsonFilter to dynamically filter the bean properties getting serialized. This works great. After adding @JsonFilter("apiFilter")
to my domain class and with the addition of this code in my jax-rs service (using the CXF implementation), I am able to dynamically filter the properties returned by my RESTful API:
// shortened for brevity
FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.filterOutAllExcept(filterProperties));
return mapper.filteredWriter(filters).writeValueAsString(user);
The problem is there are different service calls where I don't want to apply the filter at all. In those cases I want to return the entire domain class without filtering any properties. In the case where I just try to return the domain class I'm getting an exception as follows:
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not resolve BeanPropertyFilter with id 'apiFilter'; no FilterProvider configured
at org.codehaus.jackson.map.ser.BeanSerializer.findFilter(BeanSerializer.java:252)
at org.codehaus.jackson.map.ser.BeanSerializer.serializeFieldsFiltered(BeanSerializer.java:216)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:140)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我知道这个问题已经得到解答,但对于任何新人来说,杰克逊实际上添加了不会因缺少过滤器而失败的功能(JACKSON-650):
你只需要打电话
SimpleFilterProvider.setFailOnUnknownId(false)
并且您不会收到此异常。I know it's already been answered but for any newcommers Jackson has actually added the ability to not fail on missing filters (JACKSON-650):
You just need to call
SimpleFilterProvider.setFailOnUnknownId(false)
and you won't get this exception.对于 Spring Boot / Jackson 配置,只需添加:
For Spring Boot / Jackson configuration just add:
我认为您可以欺骗过滤编写器,为您希望序列化所有属性的情况定义一个空的序列化过滤器:
这样,当引擎查找在
@JsonFilter
注解中定义的“apiFilter”过滤器时,它会找到它,但不会产生任何效果(因为将序列化所有属性)。编辑
另外,您可以调用工厂方法
writer()
而不是filteredWriter()
:我认为最后一个解决方案更干净,而且确实更好。
I think you could trick the filtered writer defining an empty serialize filter for the cases where you want all the properties seralized:
This way, when the engine looks for the "apiFilter" filter defined at the
@JsonFilter
anotation, it finds it, but it will not have any effect (as will serialize all the properties).EDIT
Also, you can call the factory method
writer()
instead offilteredWriter()
:I think this last solution is way cleaner, and indeed better.
我遇到了类似的问题,得到了相同的异常,但接受的答案对我的情况并没有真正的帮助。这是对我有用的解决方案:
在我的设置中,我使用像这样的自定义 JacksonSerializer:
并且该序列化器是这样实现的:
问题是,只要您不使用任何过滤器,它就可以工作。如果您序列化基元,它也可以工作,例如,如果您使用 jgen.writeString(..) 。如果您使用过滤器,则该代码是错误的,因为过滤器存储在
SerializerProvider
内部的某个位置,而不是在JsonGenerator
中。如果在这种情况下您直接使用 jsongenerator,则会在内部创建一个不知道过滤器的新 SerializerProvider。因此,您需要调用provider.defaultSerializeValue(o, jgen)
,而不是较短的jgen.writeObject(o)
。这将确保过滤器不会丢失并且可以应用。I had a similar issue getting the same Exception, but the accepted answer didn't really help in my case. Here's the solution that worked for me:
In my setup I was using a custom JacksonSerializer like this:
And that serializer was implemented like this:
The problem with this is, that as long as you don't use any filters, it works. It also works if you serialize primitives, so for instance if you use
jgen.writeString(..)
. If you use filters, that code is wrong, because the filters are stored somewhere inside of theSerializerProvider
, not in theJsonGenerator
. If in that case you use the jsongenerator directly, a new SerializerProvider, that doesn't know about the filters, is created internally. So instead of the shorterjgen.writeObject(o)
you need to callprovider.defaultSerializeValue(o, jgen)
. That will ensure that the filters don't get lost and can be applied.这就是我为 Springboot 所做的,不需要更多的逻辑来从应用程序中的所有 REST 响应中过滤这些字段,如果您需要过滤更多 POJO,只需将它们添加到 FilterProvider 中即可:
添加带有过滤器的配置类:
添加POJO 的 JsonFilter 注释:
This is what I did for Springboot, no more logic is needed to filter those fields from all the REST responses in your application, if you need to filter more POJOs just add them to the FilterProvider:
Add a configuration class with the filter:
Add the JsonFilter annotation to your POJO:
我已经应用了与上述接受的解决方案相同的解决方案,但是当我返回 writer.writeValueAsString(course) 作为 Rest 服务响应时,我收到以下格式的响应
,但我的预期响应是
为了获取我的响应,我已应用将 jsonstring 转换为特定对象类型
注意:课程有 id、名称和评论作为字段,我想隐藏 id,
我提供的代码片段希望它对某些人有帮助。
I have applied the same solution as mentioned accepted solution but when i am returning writer.writeValueAsString(course) as a Rest service response then i am getting response in below format
But My expected Response is
For getting my response i have applied converted the jsonstring to specfic object type
Note: Course has id,name and reviews as field and i want to suppress the id
I am providing the code snippet hope it is helpful to some.