Я привык искать общие решения проблем, с которыми сталкиваюсь. И я иногда терплю неудачу в своих исследованиях лучшего решения, как и многие разработчики. Но все равно важно описать свой путь для будущего исследователя.
Проблема
Существует множество написанных API-сервисов Spring REST с множеством общих строк кода, таких как конвертеры, форматеры, пользовательские маршаллеры и т. Д. Но это все еще вопрос:
Как сделать динамические значения Spring по умолчанию для составных объектов, вводимых в контроллер REST?
Есть много вопросов и дискуссий по этому поводу [1]
Что у нас есть?
Значения по умолчанию для параметров запроса и заголовков запроса
Динамические значения параметров запроса и заголовков запроса
Сбор параметров запроса в пользовательский объект. Он не требует аннотации
RequestParamи по умолчанию не работает с заголовкамиКласс DTO:
Пример вызова:
Коллекция тела запроса в пользовательский объект
Таким образом, мы можем настроить значения по умолчанию или динамические по свойствам Spring в случаях:
| Запрос | True | True |
| Заголовок | True | True |
| Составной запрос | True | False |
| Составной заголовок | True | False |
| Тело | True | False |
Что нам нужно?
Наиболее рациональный способ – иметь механизм для указания значений по умолчанию с помощью параметров аннотаций/аннотаций, как мы делаем со значениями по умолчанию в аннотациях: @Значение , @RequestParam , @Руководитель запроса
Требования:
- Библиотека Джексона должна иметь возможность для значений по умолчанию. Существует открытый билет GitHub и примечание в документации @JsonProperty
Документация : Возможно, что в будущем эта аннотация может быть использована для значений по умолчанию, и особенно для значений по умолчанию свойств создателя, поскольку они поддерживают required() в 2.6 и выше.
- Spring должен предоставить пользовательские свойства модулю Jackson . Например:
spring.servlet:
defaults:
unit-request.value:
name: Artem
Обходной путь с помощью класса декоратора
Существует обходной путь для отдельных случаев, когда объект имеет значения по умолчанию. Самое сложное, что мы должны проверить значения, подлежащие нулю, в каждом поле, а затем использовать поле из другого.
Иметь общий интерфейс, потому что мы напишем оболочку:
Класс реализации тела запроса:
Объявлять свойства по умолчанию:
Объявить класс для свойств по умолчанию:
Объявите компонент свойств конфигурации. Пожалуйста, обратите внимание, что я предлагаю повторно использовать тот же класс
Запрос единицы измерениядля свойств, потому что это наиболее рациональный способ повторного использования существующего поведения класса. Другой способ – создать другую реализацию:Создайте класс-оболочку для использования значений из другого объекта в нулевых случаях:
Измените свой
RestControllerкод
Обходной путь с помощью прокси-класса
Это решение очень близко к многоразовому и может быть частью другого решения.
Прокси-методы веб-запроса DTO для вызова методов из другого объекта при нулевых значениях:
Код обработчика вызова:
Использование:
Плюсы
- У нас есть только одна дополнительная строка внутри контроллера
- Прокси-решение выглядит интересным для многоразовых случаев. Мы не смогли написать шаблонный код для проверки значений полей.
- Мы можем взять внутри библиотеки три класса из примера прокси-сервера.
Аферы
- Для определения значения внутренних составных полей потребуется гораздо больше строк кода. Например , когда
Запрос на единицусодержит полеПодразделение. - Это требует изменения кода контроллера, и это излишне, потому что у нас много кода Spring и Jackson сверху.
- Мы должны написать шаблонный код внутри нашей оболочки .
- Пример прокси-сервера каким-то образом применим к динамическим параметрам запроса и динамическим заголовкам, но пример оболочки – не так много.
Что я тоже пробовал?
- ОП. Я написал аспект для взаимодействия со всеми вызовами методов получения с помощью моей пользовательской аннотации. Аннотация необходима для уменьшения количества методов. Но есть сложный момент с внедрением Spring bean в аспект . Вы должны поставить
@Настраиваемыйна каждый класс DTO плюс код операции, который казался слишком рискованным, у меня много проблем на этом пути. @ControllerAdvice+@Инициализатор. Это работает и для отдельных случаев. Вы либо переопределяете все поля, либо должны проверить (как в моем обходном пути выше) значения всех полей- Прокси +
Модификатор BeanDeserializerModifier. Можно обернуть результат метода десериализации Джексона . Я завернул результат с помощью прокси-объекта, но получил файлjava.lang. Исключение IllegalArgumentException: несоответствие типа аргументаисключение. Объект типаПроксипришел к контроллеру, очевидно, что он неразрешим.
Выводы
Я хотел поделиться неудачным примером исследования программных решений в мире Java backend. Это помогает мне лучше понять библиотеку Джексона и механизмы прокси-серверов.
Продолжайте искать лучшее решение. Это расширяет кругозор в пути.
Надеюсь, что эта статья полностью описывает этот вопрос.
Проблемные ссылки
- Проблемные ссылки
- Проблемные ссылки
- Проблемные ссылки
- Проблемные ссылки
- Проблемные ссылки
- Проблемные ссылки
- Проблемные ссылки
- Проблемные ссылки
- Проблемные ссылки
Оригинал: “https://dev.to/art_ptushkin/how-not-to-make-a-framework-for-spring-default-properties-2j5f”