Динамически игнорировать свойства с JacksonJson - PullRequest
8 голосов
/ 12 августа 2011

Я знаю, что есть несколько способов заставить ДжексонаДжона игнорировать свойства при рендеринге, но все они статические. (JasonIgnore, классы MixIn, ..).

Это мой сценарий. Доменный объект может реализовать интерфейс с именем FilteredDomain для позволяют динамически фильтроваться. Интерфейс прост и предоставляет только один метод "getIgnoreProperties". (Список свойств, которые следует игнорировать).

Затем я регистрирую пользовательский сериализатор, который связывается с объектом FilteredDomain. код выглядит примерно так:

private class FilteredDomainSerializer extends JsonSerializer<FilteredDomain> {

    public void serialize(FilteredDomain arg, JsonGenerator jgen,
            SerializerProvider provder) throws IOException,
            JsonProcessingException {

        final BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(arg);

        for (PropertyDescriptor pd : wrapper.getPropertyDescriptors()) {
            final String name = pd.getName();

            if (arg.getIgnoreProperties().containsKey(name))
                continue;

            final Object value = wrapper.getPropertyValue(name);

            jgen.writeObjectField(name, value);
        }
    }
}

Во-первых, мне действительно не нравится, что мне нужно использовать оболочку Spring Bean, чтобы получить список всех свойств и выполнить итерацию по ним (Должен быть способ сделать это - Джексон Джсон).

Во-вторых, код все еще не работает. Я получаю ошибку:

org.codehaus.jackson.JsonGenerationException: невозможно записать имя поля, ожидая значение в org.codehaus.jackson.impl.JsonGeneratorBase._reportError (JsonGeneratorBase.java:480) в org.codehaus.jackson.impl.Utf8Generator.writeFieldName (Utf8Generator.java:270) в org.codehaus.jackson.JsonGenerator.writeObjectField (JsonGenerator.java:1088) в com.rootmusic.util.SystemJsonObjectMapper $ ValueObjectSerializer.serialize (SystemJsonObjectMapper.java:65) в com.rootmusic.util.SystemJsonObjectMapper $ ValueObjectSerializer.serialize (SystemJsonObjectMapper.java:1) в org.codehaus.jackson.map.ser.ContainerSerializers $ IndexedListSerializer.serializeContents (ContainerSerializers.java:304) в org.codehaus.jackson.map.ser.ContainerSerializers $ IndexedListSerializer.serializeContents (ContainerSerializers.java:254) в org.codehaus.jackson.map.ser.ContainerSerializers $ AsArraySerializer.serialize (ContainerSerializers.java:142) в org.codehaus.jackson.map.ser.MapSerializer.serializeFields (MapSerializer.java:287) в org.codehaus.jackson.map.ser.MapSerializer.serialize (MapSerializer.java:212) в org.codehaus.jackson.map.ser.MapSerializer.serialize (MapSerializer.java:23) в org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue (StdSerializerProvider.java:606) в org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue (StdSerializerProvider.java:280)

1 Ответ

8 голосов
/ 13 августа 2011

Ошибка возникает из-за того, что вы не пишете START_OBJECT / END_OBJECT вокруг пар имя-поле / значение, поэтому это легко исправить.

Что касается более динамической фильтрации, вы можете прочитать эту запись в блоге , которая включает стандартные методы. @JsonView работает, если у вас есть наборы статических определений (одно из которых вы можете динамически выбирать для каждой сериализации), но если вам нужна еще более динамичная система, @JsonFilter - это путь.

В качестве альтернативы, другим относительно простым способом было бы сначала «преобразовать» ваш POJO в карту:

Map props = objectMapper.convertValue (pojo, Map.class);

(что аналогично сериализации как JSON, за исключением того, что результатом является карта, которая будет отображаться как JSON)

, а затем выборочно обрезать Map и сериализовать это как JSON. Или, если вы предпочитаете, вы можете использовать JsonNode («модель дерева») в качестве промежуточного элемента для изменения, а затем сериализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...