Должны ли валидаторы весной обращаться к базе данных?

Я не совсем уверен, что это хорошее дизайнерское решение, чтобы заставить валидаторы проверять команды на основе состояния базы данных. Например, если мне нужно проверить bean-компонент пользователя, помимо проверки того, что адрес электронной почты и имя пользователя пусты и т. д., мне также нужно отклонить значения, если они уже используются. Должна ли такая логика быть в валидаторах или сервисных объектах?


person Vasil    schedule 25.06.2009    source источник


Ответы (6)


Что ж, ваши валидаторы — это просто Spring Bean-компоненты, так что их можно внедрять вместе с сервисными объектами, которые обрабатывают доступ к данным. Вы можете заставить своих валидаторов получать данные из базы данных без ущерба для дизайна.

person skaffman    schedule 25.06.2009
comment
Ну... Просто потому, что вы можете что-то сделать, не обязательно означает, что вы должны это делать. Я могу внедрить много неприятных вещей не в то место, что определенно поставит под угрозу дизайн системы. - person Stefan Haberl; 02.06.2020

Это во многом будет зависеть от того, как вы определяете валидацию. Подумайте вот о чем: вы что-то покупаете и вводите номер своей кредитной карты. Если контрольная цифра не совпадает, вы не прошли проверку. Транзакция не предпринималась. Однако, если это действительный номер кредитной карты, но он не соответствует вашему почтовому индексу (требуется взаимодействие с БД или третьей стороной), то это ошибка платежа.

Теперь подумайте вот о чем: вы вводите свой адрес и вводите Mastiffica в качестве своей страны. Почему система вообще позволила вам ввести это - они должны были ограничить интерфейс только допустимыми записями (в БД не требуется пост-запись).

Или введите «пятьдесят» в поле суммы на экране банковского платежа. Почему он разрешает туда буквы - это не проходит проверку (нет необходимости в БД). Но затем вы вводите 50 в поле суммы, и оказывается, что на вашем счету нет пятидесяти фунтов. Это ошибка проверки? Или это неудачная транзакция?

Теперь предположим, что вы прошли все основные проверки ввода (контрольная сумма кредитной карты, страна, цифры, почтовый индекс), и транзакция не удалась, поскольку срок действия вашей кредитной карты истек. Это ошибка проверки или неудачная транзакция?

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

Затем есть аспект проверки первой строки в качестве меры безопасности - дикие данные, которые были приняты за ваш верхний уровень пользовательского интерфейса, могут представлять угрозу безопасности (например, SQL-инъекция)

person George    schedule 25.06.2009

нет, ИМХО валидаторы должны быть небольшими и без побочных эффектов, чтобы их можно было использовать. легко комбинироваться. Безусловно, валидатор должен быть отделен от уровня постоянства.

person dfa    schedule 25.06.2009
comment
Что вы делаете, когда хотите проверить, что ссылка относится к реальному объекту? Они не должны менять данные, но иногда вам нужно сделать хотя бы проверку личности. - person Kathy Van Stone; 26.06.2009
comment
Я слышал или читал это раньше, именно поэтому я задаю вопрос. Но я не совсем уверен, что мне делать, если я не заставлю их читать из базы данных (без побочных эффектов). Я немного запутался в этой теме, потому что кажется, что многие люди в мире Java разделяют ваше мнение, в то время как в Django и RoR совершенно нормально привязывать проверку к базе данных. - person Vasil; 26.06.2009
comment
И где именно вы проверяете, указано ли имя пользователя в регистрационной форме? - person Janning; 29.08.2011
comment
Какой побочный эффект может возникнуть при чтении из базы данных? - person Mr Jedi; 01.10.2019

Я проверил один из своих и вызываю сервисный уровень из валидатора:

@Service
public final class StartFormValidator {
private FacilityService facilityService;
private AdminService adminService;

/**
 * Verify that they've selected a facility. Verify that they've selected a
 * valid facility. Verify that they've selected a view and that it's a valid
 * view.
 * 
 * @param startForm
 * @param errors
 * @return true if no errors were set
 */
public boolean isValid(final StartForm startForm, final Errors errors) {
    if (startForm.getFacilityId() == 0) {
        errors.rejectValue("facilityId", "facilityIdEmpty",
                "Select a facility.");
    }

    if (!this.facilityService.isFacilWaitlistEnabled(startForm
            .getFacilityId())) {
        errors.rejectValue("facilityId", "facilityInvalid",
                "Invalid facility");
    }

    if (StringUtils.isBlank(startForm.getPassword())) {
        errors.rejectValue("password", "passwordEmpty",
                "Enter the password.");

        return (false);
    }

    if (!this.adminService.validateAdmin(startForm.getPassword()))
        errors.rejectValue("password", "passwordInvalid",
                "Incorrect password");

    return (!errors.hasErrors());
}

/**
 * @param _facilityService
 */
@Autowired
public void setFacilityService(final FacilityService _facilityService) {
    this.facilityService = _facilityService;
}

/**
 * @param _adminService
 */
@Autowired
public void setAdminService(final AdminService _adminService) {
    this.adminService = _adminService;
}

}

person lumpynose    schedule 25.06.2009

Если вы действительно верите в "MVC", то я так не думаю, что вы хотели бы, чтобы ваши валидаторы обращались к базе данных. Проверка - это этап, который по существу проверяет данные с точки зрения бизнес-логики.

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

Тип проверки, которую вы ищете, будет рассматриваться как часть бизнес-объектов, что гарантирует, что еще до того, как объекты службы будут вызваны; такой комбинации еще не существует.

Сервисные объекты также не должны содержать бизнес-проверки, поэтому они не относятся ни к валидаторам, ни к сервисным объектам. Но да, если приложение достаточно маленькое, чтобы не беспокоиться о слишком большом количестве слоев, асимметричный подход хорош, но только до тех пор, пока «он соблюдается как стандарт во всем».

Короче говоря, я чувствую, что весенние валидаторы предназначены для базовых проверок, а не для бизнес-проверок.

person Priyank    schedule 26.06.2009

я предпочитаю проверку, которая использует базу данных из-за удобства использования конечным пользователем.

При отправке регистрационной формы вы хотите проверить, является ли имя пользователя синтаксически правильным и не задано ли это имя пользователя (требуется доступ к БД).

Форма может вернуться со всеми ошибками сразу. Он может показать пользователю все проблемы. Пользователь может исправить это и снова отправить форму.

Я знаю, что вы можете сделать это умнее с помощью ajax и т. Д., Это не главное.

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

person Janning    schedule 29.08.2011