@JsonFilter выдает «JsonMappingException: не удается разрешить BeanPropertyFilter» - PullRequest
15 голосов
/ 21 февраля 2012

Можно ли выборочно определить, когда аннотация @JsonFilter используется во время выполнения?

Я получаю исключение JsonMappingException (см. Ниже), когда я не предоставляю фильтр.

Справочная информация:

Я узнал из недавнего поста StackOverflow , что я могу использовать @JsonFilter для динамической фильтрации свойств бина, получающих сериализацию. Это прекрасно работает. После добавления @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)

Ответы [ 3 ]

24 голосов
/ 20 марта 2012

Я знаю, что на него уже ответили, но для любого новичка Джексон фактически добавил возможность не пропадать на отсутствующих фильтрах ( JACKSON-650 ):
Вам просто нужно позвонить SimpleFilterProvider.setFailOnUnknownId(false) и вы не получите это исключение.

7 голосов
/ 21 февраля 2012

Я думаю, вы могли бы обмануть фильтрующего писателя, определяющего пустой фильтр сериализации, для случаев, когда вы хотите, чтобы все свойства были разделены:

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

Таким образом, когда движок ищет фильтр «apiFilter», определенный в аннотации @JsonFilter, он находит его, но он не будет иметь никакого эффекта (так как все свойства будут сериализованы).

EDIT Также вы можете вызвать фабричный метод 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);

Я думаю, что последнее решение намного чище и даже лучше.

0 голосов
/ 06 февраля 2018

У меня была похожая проблема с тем же исключением, но принятый ответ не помог мне в моем случае. Вот решение, которое сработало для меня:

В моей настройке я использовал пользовательский JacksonSerializer, как это:

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

И этот сериализатор был реализован так:

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

Проблема в том, что, пока вы не используете фильтры, все работает. Это также работает, если вы сериализуете примитивы, например, если вы используете jgen.writeString(..). Если вы используете фильтры, этот код неверен, потому что фильтры хранятся где-то внутри SerializerProvider, а не в JsonGenerator. Если в этом случае вы используете jsongenerator напрямую, новый SerializerProvider, который не знает о фильтрах, создается внутри. Поэтому вместо короткого jgen.writeObject(o) вам нужно позвонить provider.defaultSerializeValue(o, jgen). Это гарантирует, что фильтры не будут потеряны и могут быть применены.

...