Пользовательское поле игнорирования на основе аннотаций из сериализации

Рассмотрим случай, когда у меня есть 2 экземпляра Object Mapper. Я хочу, чтобы из сериализации были исключены поля, аннотированные какой-либо пользовательской аннотацией, в то время как другой картограф включает (игнорирует аннотацию)

Например, класс имеет 3 поля a, b, c, а c аннотирован некоторой аннотацией (скажем, @IgnoreField) (их будет n количество классов, каждый будет иметь свои поля, которые не предназначены для сериализации)

Теперь 1-й преобразователь объектов o1 должен сериализовать только a и b. В то время как второй сопоставитель объектов o2 может сериализовать a, b и c.

Это может произойти с любым классом, имеющим разные поля, некоторые из которых могут быть аннотированы.


person Rajat Jindal    schedule 24.09.2019    source источник
comment
Что за вопрос?   -  person BeUndead    schedule 24.09.2019
comment
ты нашел решение?   -  person Eugen    schedule 24.09.2019


Ответы (4)


Вы всегда можете реализовать собственный JsonSerializer и зарегистрировать его в своем ObjectMapper.

class Bean {
    @Ignore
    String a;
    String b;
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Ignore {

}

class BeanWithIgnoredFieldsSerializer extends JsonSerializer<Bean> {

    @Override
    public void serialize(final Bean value, final JsonGenerator gen, final SerializerProvider serializers) throws IOException, JsonProcessingException {
        gen.writeStartObject();
        try {
            for (final Field f : Bean.class.getFields()) {
                if (f.isAnnotationPresent(Ignore.class)) {
                    gen.writeStringField(f.getName(), (String) f.get(value));
                }
            }
        } catch (final Exception e) {
            //
        }
        gen.writeEndObject();
    }

}

class BeanModule extends SimpleModule {

    BeanModule() {
        addSerializer(Bean.class, new BeanWithIgnoredFieldsSerializer());
    }
}

void configure(final ObjectMapper om) {
    om.registerModule(new BeanModule());
}

Примечание. Я не тестировал этот код, но это общая идея добавления пользовательских сериализаторов в OM. Измените код в методе serialize по своему усмотрению.

person sfiss    schedule 24.09.2019
comment
Если вы считаете, что он правильно отвечает на ваш вопрос, вы можете и, вероятно, должны отметить его как принятый. Также примите во внимание то, что сказал GhostCat, и, возможно, подумайте, действительно ли вы хотите реализовать это таким образом. - person sfiss; 11.10.2019

Попробуйте настроить SimpleBeanPropertyFilter для другого состояния.

@JsonFilter("someBeanFilter")
public class SomeBean {
}

SimpleFilterProvider filterProvider = new SimpleFilterProvider();
filterProvider.addFilter("someBeanFilter",SimpleBeanPropertyFilter.serializeAllExcept("aFild")); 

ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider); 
person Eugen    schedule 24.09.2019

Я бы посоветовал вам попробовать пользовательскую аннотацию здесь, с помощью которой вы можете разместить аннотацию в нужном поле и в любом нет. классов. Итак, используя отражение, которое является ключевой концепцией пользовательской аннотации, вы можете определить поведение, что делать с этой аннотацией. Проверьте этот пример:

Пример пользовательской аннотации

person VISHAL AGGARWAL    schedule 24.09.2019
comment
ОП знает о пользовательских аннотациях. Суть его вопроса не в этом, поэтому ваш ответ... ничего не отвечает. - person GhostCat; 24.09.2019

Отчетливое отсутствие ответа:

Это, скорее всего, ужасная идея.

Вы пишете код, чтобы сообщить о своем намерении. Когда вы используете эту аннотацию, вы говорите «всем», что эти поля следует игнорировать.

Читатель-человек, просматривающий ваш код, может потратить полдня, спрашивая себя позже: «там написано @IgnoreField вместо a и c, так какого черта a и c отображают сериализованные данные?»

Другими словами, какую бы проблему вы ни пытались здесь решить, ответ, скорее всего, будет не путем взлома вашего пути к игнорированию аннотаций иногда.

Следующим лучшим «разумным» решением может быть: полагаться на различные пользовательские аннотации, такие как @IgnoreAlways и что-то вроде @OnlyIncludeForXyz. Другими словами: четко выразить то, что может произойти. Вместо того, чтобы использовать декларативное программирование, чтобы затем «солгать» о том, что вы объявили.

person GhostCat    schedule 24.09.2019
comment
Я понял вашу точку зрения, но это был просто пример фактической аннотации @FieldDescriptor с некоторыми свойствами. - person Rajat Jindal; 24.09.2019
comment
@RajatJindal хорошо, тогда ты должен был так сказать. Вот почему люди предлагают всегда предоставлять минимально воспроизводимый пример вместо того, чтобы просто описывать свою проблему расплывчато. условия. - person GhostCat; 24.09.2019