2020-01-16 19:03:05 Четверг
Разработка среды: jdk1.8
, maven3.5.0
, spring boot 2.0.2.RELEASE
В процессе разработки Java-приложений, многие проекты не выполняют проверку параметров интерфейсов или используют простые методы проверки с помощью if-выражений. Это связано с несколькими причинами:
Hibernate Validator — это фреймворк для проверки данных в Hibernate, который является эталонной реализацией Bean Validation. Он широко используется и может быть применён для создания собственной системы проверки параметров. Однако при использовании Hibernate Validator для разных методов могут потребоваться разные правила проверки, что приводит к необходимости создания нескольких классов сущностей или групп, а иногда даже к отсутствию параметров у некоторых интерфейсов. Поэтому использование Hibernate Validator может вызвать определённые трудности.
На основе этого опыта я разработал собственную систему проверки параметров интерфейса на основе AOP и аннотаций.
Для проверки параметров используются аннотации @CheckParam
или @CheckParams
. Вот пример использования этих аннотаций:
@RestController
@RequestMapping("/paramCheck")
public class ParamCheckController {
@CheckParam(value = Check.NotEmpty, argName = "userName", msg = "Ты большой дядя, это обязательный параметр!")
@PostMapping("/singleCheckNotEmpty")
public Object singleCheckNotNull(String userName) {
return 1;
}
@CheckParam(value = Check.DateTime, argName = "dateTime", msg = "msg можно не указывать, есть стандартное сообщение")
@PostMapping("/singleCheckDateTime")
public Object singleCheckDateTime(String dateTime) {
return 1;
}
@CheckParams({
@CheckParam(value = Check.NotNull, argName = "userId", msg = "Ты большой дядя, этот параметр обязателен!"),
@CheckParam(value = Check.NotEmpty, argName = "userName"),
@CheckParam(value = Check.NotEmpty, argName = "dept.deptName", msg = "Проверка атрибутов сущности"),
@CheckParam(value = Check.Past, argName = "dept.createTime"),
@CheckParam(value = Check.lt, argName = "dept.employees", express = "2") // Проверка размера коллекции
})
@PostMapping("/entityMultiCheck")
public Object entityMultiCheck(Integer userId, String userName, @RequestBody DeptEntity dept) {
return 1;
}}
@CheckParam
или @CheckParams
для указания параметров, подлежащих проверке.Вот перечисление Check, которое содержит различные типы проверок:
public enum Check {
Null("Параметр должен быть null", CheckUtil::isNull),
NotNull("Параметр не должен быть null", CheckUtil::isNotNull),
Empty("Параметр должен быть пустым", CheckUtil::isEmpty),
NotEmpty("Параметр не должен быть пустым", CheckUtil::isNotEmpty),
True("Параметр должен быть true", CheckUtil::isTrue),
False("Параметр должен быть false", CheckUtil::isFalse),
Date("Параметр должен представлять собой дату в формате yyyy-MM-dd", CheckUtil::isDate),
DateTime("Параметр должен представлять собой дату и время в формате yyyy-MM-dd HH:mm:ss", CheckUtil::isDateTime),
Past("Параметр должен представлять прошедшую дату", CheckUtil::isPast),
Future("Параметр должен представлять будущую дату", CheckUtil::isFuture),
Today("Параметр должен представлять сегодняшнюю дату", CheckUtil::isToday),
Enum("Параметр должен принадлежать перечислению", CheckUtil::inEnum),
Email("Параметр должен быть адресом электронной почты", CheckUtil::isEmail),
Range("Параметр должен находиться в допустимом диапазоне", CheckUtil::inRange),
NotIn("Параметр должен не находиться в указанном диапазоне", CheckUtil::outRange),
Length("Длина параметра должна находиться в заданном диапазоне", CheckUtil::inLength),
gt("Параметр должен быть больше указанного значения", CheckUtil::isGreaterThan),
lt("Параметр должен быть меньше указанного значения", CheckUtil::isLessThan),
ge("Параметр должен быть больше или равен указанному значению", CheckUtil::isGreaterThanEqual),
le("Параметр должен быть меньше или равен указанному значению", CheckUtil::isLessThanEqual),
ne("Параметр должен отличаться от указанного значения", CheckUtil::isNotEqual),
Equal("Параметр должен совпадать с указанным значением", CheckUtil::isEqual),
Pattern("Параметр должен соответствовать указанному регулярному выражению", CheckUtil::isPattern);
public String msg;
public BiFunction<Object, String, Boolean> fun;
Check(String msg, BiFunction<Object, String, Boolean> fun) {
this.msg = msg;
this.fun = fun;
}
}
Если вы хотите узнать больше, вы можете скачать исходный код и изучить его подробнее.
@SpringBootApplication(scanBasePackages = {"com.yuxue"})
, чтобы все аннотации были просканированы.<dependency>
<groupId>com.yuxue</groupId>
<artifactId>yx-validator</artifactId>
<version>1.0.0</version>
</dependency>
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yuxue.entity.DeptEntity;
import com.yuxue.entity.EmployeeEntity;
import com.yuxue.validator.annotation.CheckParam;
import
``` ```
com.yuxue.validator.annotation.CheckParams;
import com.yuxue.validator.enumtype.Check;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@Api(tags = {"check"}, description = "Параметр проверки")
@RestController
@RequestMapping("/paramCheck")
public class ParamCheckController {
@ApiImplicitParam(name = "userId", value = "", dataType = "Integer", paramType="query")
@CheckParam(value = Check.NotNull, argName = "userId")
@PostMapping("/singleCheckNotNull")
public Object singleCheckNotNull(Integer userId) {
System.err.println(userId);
return 1;
}
@ApiImplicitParam(name = "userName", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.NotEmpty, argName = "userName", msg = "Ты большой дядя, это обязательный параметр!")
@PostMapping("/singleCheckNotEmpty")
public Object singleCheckNotNull(String userName) {
System.err.println(userName);
return 1;
}
@ApiImplicitParam(name = "bl", value = "", dataType = "Boolean", paramType="query")
@CheckParam(value = Check.True, argName = "bl")
@PostMapping("/singleCheckTrue")
public Object singleCheckTrue(Boolean bl) {
System.err.println(bl);
return 1;
}
@ApiImplicitParam(name = "date", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.Date, argName = "date")
@PostMapping("/singleCheckDate")
public Object singleCheckDate(String date) {
System.err.println(date);
return 1;
}
@ApiImplicitParam(name = "dateTime", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.DateTime, argName = "dateTime")
@PostMapping("/singleCheckDateTime")
public Object singleCheckDateTime(String dateTime) {
System.err.println(dateTime);
return 1;
}
@ApiImplicitParam(name = "date", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.Past, argName = "date")
@PostMapping("/singleCheckPast")
public Object singleCheckPast(String date) {
System.err.println(date);
return 1;
}
@ApiImplicitParam(name = "dateTime", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.Future, argName = "dateTime", msg = "Параметр должен быть будущей датой или временем и соответствовать формату yyyy-MM-dd HH:mm:ss.")
@PostMapping("/singleCheckFuture")
public Object singleCheckFuture(String dateTime) {
System.err.println(dateTime);
return 1;
}
@ApiImplicitParam(name = "date", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.Today, argName = "date")
@PostMapping("/singleCheckToday")
public Object singleCheckToday(String date) {
System.err.println(date);
return 1;
}
@ApiImplicitParam(name = "gender", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.Enum, argName = "gender", express="мужчина, женщина, евнух")
@PostMapping("/singleCheckStringEnum")
public Object singleCheckStringEnum(String gender) {
System.err.println(gender);
return 1;
}
@ApiImplicitParam(name = "gender", value = "", dataType = "Integer", paramType="query")
@CheckParam(value = Check.Enum, argName = "gender", express="0,1")
@PostMapping("/singleCheckIntegerEnum")
public Object singleCheckIntegerEnum(Integer gender) {
System.err.println(gender);
return 1;
}
@ApiImplicitParam(name = "password", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.Length, argName = "password", express="6,18", msg="Длина пароля должна быть от 6 до 18 символов!")
@PostMapping("/singleCheckStringLength")
public Object singleCheckStringLength(String password) {
System.err.println(password);
return 1;
}
@ApiImplicitParam(name = "password", value = "", dataType = "String", paramType="query")
@CheckParams({
@CheckParam(value = Check.ge, argName = "password", express = "6"),
``` Вот перевод текста на русский язык:
@CheckParam(value = Check.le, argName = "password", express = "18")
})
@PostMapping("/singleCheckStringLength1")
public Object singleCheckStringLength1(String password) {
System.err.println(password);
return 1;
}
@ApiImplicitParam(name = "age", value = "", dataType = "Integer", paramType="query")
@CheckParam(value = Check.Range, argName = "age", express="18,50")
@PostMapping("/singleCheckIntegerRange")
public Object singleCheckIntegerRange(Integer age) {
System.err.println(age);
return 1;
}
@ApiImplicitParam(name = "age", value = "", dataType = "Integer", paramType="query")
@CheckParams({
@CheckParam(value = Check.ge, argName = "age", express="18"),
@CheckParam(value = Check.le, argName = "age", express="50")
})
@PostMapping("/singleCheckIntegerRange1")
public Object singleCheckIntegerRange1(Integer age) {
System.err.println(age);
return 1;
}
@ApiImplicitParam(name = "age", value = "", dataType = "Integer", paramType="query")
@CheckParam(value = Check.NotIn, argName = "age", express="18,50")
@PostMapping("/singleCheckIntegerNotIn")
public Object singleCheckIntegerNotIn(Integer age) {
System.err.println(age);
return 1;
}
@ApiImplicitParam(name = "age", value = "", dataType = "Integer", paramType="query")
@CheckParams({
@CheckParam(value = Check.lt, argName = "age", express="18"),
@CheckParam(value = Check.gt, argName = "age", express="50")
})
@PostMapping("/singleCheckIntegerNotIn1")
public Object singleCheckIntegerNotIn1(Integer age) {
System.err.println(age);
return 1;
}
@ApiImplicitParam(name = "email", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.Email, argName = "email", msg="你大爷的,输入个邮箱啊!")
@PostMapping("/singleCheckEmail")
public Object singleCheckEmail(String email) {
System.err.println(email);
return 1;
}
@ApiImplicitParam(name = "age", value = "", dataType = "Integer", paramType="query")
@CheckParam(value = Check.ge, argName = "age", express="18", msg = "必须大于等于18岁") // gt、lt、le、ne、Equal不再举例; 具体看注释
@PostMapping("/singleCheckIntegerGe")
public Object singleCheckIntegerGe(Integer age) {
System.err.println(age);
return 1;
}
@ApiImplicitParam(name = "pattern", value = "", dataType = "String", paramType="query")
@CheckParam(value = Check.Pattern, argName = "pattern", express="^[\u0021-\u007E]{4,16}$")
@PostMapping("/singleCheckPattern")
public Object singleCheckPattern(String pattern) {
System.err.println(pattern);
return 1;
}
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", dataType = "Integer", paramType="query"),
@ApiImplicitParam(name = "userName", dataType = "String", paramType="query")
})
@CheckParams({
@CheckParam(value = Check.NotNull, argName = "userId", msg = "你大爷的,这个是必填参数!"),
@CheckParam(value = Check.NotNull, argName = "userName")
})
@PostMapping("/multiCheckNotNull")
public Object multiCheckNotNull(Integer userId, String userName) {
System.err.println(userId);
System.err.println(userName);
return 1;
}
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", dataType = "Integer", paramType="query"),
@ApiImplicitParam(name = "userName", dataType = "String", paramType="query"),
@ApiImplicitParam(name = "employee", dataType = "entity", paramType="body")
})
@CheckParams({
@CheckParam(value = Check.NotNull, argName = "userId", msg = "你大爷的,这个是必填参数!"),
@CheckParam(value = Check.NotEmpty, argName = "userName"),
@CheckParam(value = Check.NotEmpty, argName = "employee.name")
})
@PostMapping("/entityCheckNotNull")
public Object entityCheckNotNull(Integer userId, String userName, @RequestBody EmployeeEntity employee) {
System.err.println(userId); ```
System.err.println(userName);
System.err.println(employee.getName());
return 1;
}
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", dataType = "Integer", paramType="query"),
@ApiImplicitParam(name = "userName", dataType = "String", paramType="query"),
@ApiImplicitParam(name = "dept", dataType = "entity", paramType="body")
})
@CheckParams({
@CheckParam(value = Check.NotNull, argName = "userId", msg = "你大爷的,这个是必填参数!"),
@CheckParam(value = Check.NotEmpty, argName = "userName"),
@CheckParam(value = Check.NotEmpty, argName = "dept.deptName"),
@CheckParam(value = Check.Past, argName = "dept.createTime"),
@CheckParam(value = Check.lt, argName = "dept.employees", express = "2") // 对集合的size判断
})
@PostMapping("/entityMultiCheck")
public Object entityMultiCheck(Integer userId, String userName, @RequestBody DeptEntity dept) {
System.err.println(userId);
System.err.println(userName);
System.err.println(dept.getDeptName());
return 1;
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )