@JsonFilter throws “JsonMappingException: Can not resolve BeanPropertyFilter”

后端 未结 4 1232
無奈伤痛
無奈伤痛 2021-01-01 17:46

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 p

相关标签:
4条回答
  • 2021-01-01 17:58

    I think you could trick the filtered writer defining an empty serialize filter for the cases where you want all the properties seralized:

    FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.serializeAllExcept(emptySet));
    

    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 of 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);
    

    I think this last solution is way cleaner, and indeed better.

    0 讨论(0)
  • 2021-01-01 17:58

    For Spring Boot / Jackson configuration just add:

    @Configuration 
    public class JacksonConfiguration { 
        public JacksonConfiguration(ObjectMapper objectMapper) { 
            objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false)); 
        } 
    }
    
    0 讨论(0)
  • 2021-01-01 18:15

    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.

    0 讨论(0)
  • 2021-01-01 18:18

    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:

    @JsonSerialize(using = MyCustomSerializer.class)
    private Object someAttribute;
    

    And that serializer was implemented like this:

    public class MyCustomSerializer extends JsonSerializer<Object> {
      @Override
      public void serialize(Object o, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        if (o != null) {
          jgen.writeObject(o);
        }
      }
    }
    

    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 the SerializerProvider, not in the JsonGenerator. 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 shorter jgen.writeObject(o) you need to call provider.defaultSerializeValue(o, jgen). That will ensure that the filters don't get lost and can be applied.

    0 讨论(0)
提交回复
热议问题