Используется fluent-validator для валидации данных, а также выполняется расширение fluent.
Пакет Hibernate Validator уже достаточно хорош для серверной проверки данных. Fluent-validator объединяет возможности Hibernate Validator с удобным API для последовательной проверки данных. Однако способ @FluentValidate({xx.class})
и использование пользовательских аннотаций Hibernate Validator аналогичны и предназначены для базовой проверки отдельных свойств объекта, а не для бизнес-логики.
Например, одно свойство объекта может зависеть от значения другого свойства. Например, если требуется предоставление номера телефона, то этот номер не должен быть пустым.
В ходе работы над проектом было выявлено множество ситуаций, требующих бизнес-логики проверки данных. Поэтому были сделаны простые расширения для удовлетворения этих потребностей.
@Dict
— выбор одного значения из словаря@DictMulti
— выбор нескольких значений из словаряUrl
— проверка корректности URLIdcardValidator
- проверка корректности номера паспортаPhoneValidator
- проверка корректности номера телефонаUrlValidator
- проверка корректности URL (необходимость создания пользовательского сообщения об ошибке)ZipCodeValidator
- проверка корректности почтового индекса## 2. Почему требуется выполнение бизнес-логики проверки данных на сервереДля обеспечения безопасности сайты обычно используют клиентскую и серверную проверку данных. Серверная проверка позволяет фильтровать данные, отправляемые не через интерфейсы сайта, что снижает количество мусора в базе данных.
Выполнение бизнес-логики проверки данных повышает качество данных путём добавления дополнительных условий проверки.
Создание пользовательской аннотации @Refer
, которая позволяет выполнять бизнес-логику проверки данных. Аннотация объединяет преимущества Fluent Validator и Hibernate Validator.```java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Refer {
String[] param(); // параметры для условия проверки
String[] validParam() default {}; // параметры для проверки значений, если не указаны, берутся из аннотации
Class<?> validator(); // класс валидатора
String message() default ""; // сообщение об ошибке
}
```markdown
Класс <?>[] группы() по умолчанию {}; // группировка
}
Использование:
@Refer(validator = AOneBNotNullValidator.class,
groups = {G1.class},
param = {"org.mango.bean.C:c1=110"},
message = "значение c2 должно быть заполнено при условии c1=110")
private String c2;
Валидатор:
/**
* @param param условие параметра
* @param validparam валидационный параметр
* @param vc контекст валидации
* @param msg сообщение об ошибке
* @return
*/
@Override
public boolean validate(Map<String, Object> param, Map<String, Object> validparam, ValidContext vc, String msg) {
String bb = this.getString(param, this.getFirstKey(param));
String eqValue = this.getString(param, this.getFirstKey(param) + "_eqValue");
if (bb != null) {
String field = this.getFirstKey(validparam);
String str = this.getString(validparam, field);
if (bb.equals(eqValue)) {
if (str != null && str.length() > 0) {
return true;
} else {
vc.addError(field, msg);
return false;
}
} else {
return true;
}
}
return true;
}
Валидация теста:
public static void main(String[] args) {
C aObj = new C();
aObj.setA0(1);
aObj.setA1("test");
aObj.setA2("");
B b = new B();
b.setB1("mango");
b.setB3("xxx");
aObj.setB(b);
try {
List<String> msgList = ValidUtil.validateAll(aObj, true);
System.out.println(JSONObject.toJSONString(msgList));
} catch (Exception e) {
e.printStackTrace();
}
}
# 5.
```Дополнительные методы валидации
> больше в <a href="https://gitee.com/mangoorg/mei-fluent-demo/blob/master/fluent-demo/src/main/java/org/mango/validator/util/ValidUtil.java?oid=53e5119b4f8907bfc968242a785ff73384c4847d">ValidUtil.java</a>
# 6. Недостатки решённые с помощью @Refer
* param = {"org.mango.bean.C:c1=110"} передача параметров, гибкая передача нескольких параметров, реализует сценарий бизнес-логики типа if(a1 == 1 && b1 == 1) {c1 и c2 не должны быть пустыми}.
* Базируясь на аннотации @Valid, реализован рекурсивный анализ свойства List или объекта.
* Используя метод class.getSuperclass(), получаем родительское свойство, расширенное через extends.
* org.mango.bean.
C:c1=110, Класс C не является текущим классом, используйте локальный поточно-безопасный map объекта для хранения свойства bean, чтобы обеспечить зависимость между свойствами разных beans.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )