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
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.
For Spring Boot / Jackson configuration just add:
@Configuration
public class JacksonConfiguration {
public JacksonConfiguration(ObjectMapper objectMapper) {
objectMapper.setFilterProvider(new 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.
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.