Как динамически игнорировать свойство при сериализации Джексона - PullRequest
0 голосов
/ 04 июля 2018

У меня есть объект с несколькими ассоциациями @ManyToOne. Я использую приложение весенней загрузки для предоставления REST API. В настоящее время у меня есть несколько API REST с возвращаемым json-ответом всей сущности, включая ассоциации.

Но я не хочу сериализовать все связанные объекты во всех REST API. Например

API-1 должен возвращать объект parent + associationA API-2 должен вернуть объект parent + associationA + associationB API-3 должен вернуть родителя + ассоциациюB + ассоциациюc + ассоциациюD

Итак, в моем процессе сериализации я хочу игнорировать все ассоциации, кроме ассоциации А для API-1. Для API-2 я хочу игнорировать другие ассоциации, кроме A и B

Как динамически игнорировать эти свойства во время сериализации Джексона.

Примечания: У меня такой же класс, мне не интересно создавать какие-либо dto для каждого API

Любые предложения приветствуются.

1 Ответ

0 голосов
/ 04 июля 2018

Я собрал три подхода для выполнения динамической фильтрации в Джексоне. Один из них должен соответствовать вашим потребностям.

Использование @JsonView

Вы можете использовать @JsonView:

public class Views {         
    interface Simple { }  
    interface Detailed extends Simple { }   
}
public class Foo {

    @JsonView(Views.Simple.class)
    private String name;

    @JsonView(Views.Detailed.class)
    private String details;

    // Getters and setters
}
@RequestMapping("/foo")
@JsonView(Views.Detailed.class)
public Foo getFoo() {
    Foo foo = new Foo();
    return foo;
}

В качестве альтернативы вы можете установить вид динамически с помощью MappingJacksonValue.

@RequestMapping("/foo")
public MappingJacksonValue getFoo() {
    Foo foo = new Foo();
    MappingJacksonValue result = new MappingJacksonValue(foo);
    result.setSerializationView(Views.Detailed.class);
    return result;
}

Использование BeanSerializerModifier

Вы можете расширить BeanSerializerModifier, а затем переопределить метод changeProperties(). Он позволяет добавлять, удалять или заменять любые свойства для сериализации в соответствии с вашими потребностями:

public class CustomSerializerModifier extends BeanSerializerModifier {

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
        BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {

        // In this method you can add, remove or replace any of passed properties

        return beanProperties;
    }
}

Затем зарегистрируйте сериализатор как модуль в вашем ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule() {

    @Override
    public void setupModule(SetupContext context) {
        super.setupModule(context);
        context.addBeanSerializerModifier(new CustomSerializerModifier());
    }
});

Проверьте примеры здесь и здесь .

Использование @JsonFilter с SimpleBeanPropertyFilter

Другой подход включает @JsonFilter:

@JsonFilter("customPropertyFilter")
public class Foo {

    private String name;
    private String details;

    // Getters and setters
}

Расширьте SimpleBeanPropertyFilter и переопределите метод serializeAsField() в соответствии с вашими потребностями:

public class CustomPropertyFilter extends SimpleBeanPropertyFilter {

    @Override
    public void serializeAsField(Object pojo, JsonGenerator jgen,
                                 SerializerProvider provider, 
                                 PropertyWriter writer) throws Exception {

        // Serialize a field
        // writer.serializeAsField(pojo, jgen, provider, writer);

        // Omit a field from serialization
        // writer.serializeAsOmittedField(pojo, jgen, provider);
    }
}

Затем зарегистрируйте фильтр в вашем ObjectMapper:

FilterProvider filterProvider = new SimpleFilterProvider()
        .addFilter("customPropertyFilter", new CustomPropertyFilter());

ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);

Если вы хотите сделать свой фильтр «глобальным» , то есть применить его ко всем bean-компонентам, вы можете создать смешанный класс и аннотировать его с помощью @JsonFilter("customPropertyFilter"):

@JsonFilter("customPropertyFilter")
public class CustomPropertyFilterMixIn {

}

Затем привяжите смешанный класс к Object:

mapper.addMixIn(Object.class, CustomPropertyFilterMixIn.class);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...