@JsonFilter抛出"JsonMappingException:无法解析BeanPropertyFilter"

Jus*_*tin 15 json cxf jax-rs jackson

是否有可能选择性地确定@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);
Run Code Online (Sandbox Code Playgroud)

问题是有不同的服务调用,我根本不想应用过滤器.在这些情况下,我想返回整个域类而不过滤任何属性.在我只是尝试返回域类的情况下,我得到一个例外,如下所示:

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)
Run Code Online (Sandbox Code Playgroud)

Itt*_*tai 26

我知道它已经得到了回答但是对于任何新手来说,杰克逊实际上已经添加了不丢失过滤器的能力(JACKSON-650):
你只需要打电话 SimpleFilterProvider.setFailOnUnknownId(false),你就不会得到这个例外.

  • 当然,即使您不打算使用您正在使用的映射器进行过滤,您仍然需要配置SimpleFilterProvider.那好吧. (5认同)

小智 12

对于 Spring Boot / Jackson 配置,只需添加:

@Configuration 
public class JacksonConfiguration { 
    public JacksonConfiguration(ObjectMapper objectMapper) { 
        objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false)); 
    } 
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*ros 9

我想你可以欺骗过滤后的编写器定义一个空的序列化过滤器,以便你想要所有属性被分类:

FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.serializeAllExcept(emptySet));
Run Code Online (Sandbox Code Playgroud)

这样,当引擎查找在anotation中定义的"apiFilter"过滤器时@JsonFilter,它会找到它,但它不会产生任何影响(因为它将序列化所有属性).

编辑 此外,您可以调用工厂方法writer()而不是filteredWriter():

ObjectWriter writer=null;
if(aplyFilter) {
    FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.filterOutAllExcept(filterProperties));
    writer=mapper.filteredWriter(filters);
} else {
   writer=mapper.writer();
}

return writer.writeValueAsString(user);
Run Code Online (Sandbox Code Playgroud)

我认为最后的解决方案更清洁,更确切.