Недавно начал переходить с оригинальной инженерки Android на Java Web.Не много ерунды,картинка выше
задний план
JSR 303 — Bean Validation — это спецификация для проверки данных, завершенная в ноябре 2009 года. Hibernate Validator является эталонной реализацией Bean Validation. Hibernate Validator предоставляет все встроенные ограничения в спецификации JSR 303. Обычно мы проверяем и оцениваем входящие параметры при написании интерфейса, например, не является ли строка пустой, сколько значений возвращается и т. д. Для этого необходимо использовать проверку параметров Spring, здесь мы используем spring-boot-starter- веб-пакет содержит пакет hibernate-validator,
Существует несколько способов проверки параметров, а именно:
- 1. Используйте @Valid+BindingResult
- 2. Аннотировать с помощью @Valid + глобальная обработка захвата исключений
Ниже описано использование этих двух методов.
Проверка с параметрами @Valid+BindingResult
1. В соответствии с международной спецификацией JSP 303 сначала определите bean-компонент, а другие добавляют аннотации проверки к имени поля, имя поля @NotBlank не может быть нулевым, а длина больше 0. Общие типы проверки:
Constraint 详细信息
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
/**
* @author Lang.Chen
* @date 2018/6/20 下午4:39
*/
public class User {
//账号
@NotBlank(message = "账号不能为空")
private String phone;
//密码
@NotBlank(message = "密码不能为空")
private String password;
public void setPhone(String phone) {
this.phone = phone;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public String getPassword() {
return password;
}
}
2. Добавьте проверку @Valid+BindingResult в соответствующий интерфейс в классе Controller.После добавления, если проверка параметра не удалась, перейдите непосредственно к оператору if и верните результат в операторе.
if(bindingResult.hasErrors()){
}
@RestController
@RequestMapping(value = "/user")
public class UserController implements IUser {
@Override
@RequestMapping(value = "/login", method = RequestMethod.POST)
public User login( @Valid User userInfo, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
System.out.print(bindingResult.getFieldError().getDefaultMessage());
return null;
}
return userInfo;
}
}
Что ж, мы закончили первую проверку, но подумайте хорошенько, если у меня несколько интерфейсов, нужно ли мне каждый раз писать @Valid+BindgResult bingingResult, а затем переходить к оператору If, чтобы судить, если это только Ошибка информация противоречива, но возвращенная структура клиента непротиворечива, например
{"code":"1002","message":"parameters are missing","data":"{}"}
Разным проверкам нужно только изменить сообщение, а затем можно ли его обрабатывать единообразно, чтобы уменьшить объем кода, поэтому второй метод представлен ниже.
Используйте @Valid + глобальную проверку параметров захвата исключений.
Проще говоря, удалите BindingResult из первого метода, а затем определите глобальный класс исключения, такой же
1. Или определить POJO
/**
* @author Lang.Chen
* @date 2018/6/20 下午4:39
*/
public class User {
//账号
@NotBlank(message = "账号不能为空")
private String phone;
//密码
@NotBlank(message = "密码不能为空")
private String password;
public void setPhone(String phone) {
this.phone = phone;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public String getPassword() {
return password;
}
}
2. Метод в контроллере определяет @Valid для проверки
public class UserController implements IUser {
@Override
@RequestMapping(value = "/login2", method = RequestMethod.POST)
public User login2(@RequestBody @Valid User userInfo) {
return null;
}
}
3. Определите глобальный класс исключений
Все результаты неудачной проверки будут зафиксированы в методе defaultExcepitonHandler класса GlobalExceptionHandler.
@RestControllerAdvice
@Component
public class GlobleExceptionHandler {
@ResponseBody
@ExceptionHandler(Exception.class)
public String defultExcepitonHandler(Exception ex) {
ex.printStackTrace();
if(ex instanceof BindException){
//处理返回的错误信息
StringBuffer errorMsg = new StringBuffer();
BindException c = (BindException) ex;
List<ObjectError> errors = c.getBindingResult().getAllErrors();
for (ObjectError error : errors) {
errorMsg.append(error.getDefaultMessage()).append(";");
}
return errorMsg.toString();
}
return "";
}
}
Что касается пользовательской проверки и групповой проверки, я не буду вводить их одну за другой, а воспользуюсь двумя вышеуказанными.
Q&A
1. Как использовать один параметр для проверки и ввода глобального захвата исключения, возврата?
Иногда, когда передается только несколько проверок, мы не можем создать новый объект для принятия. Как использовать проверку одного параметра в это время? Посмотрите онлайн-использование и добавьте его в класс параметр @Validated, а затем через глобальный метод захвата исключений
@RestController
@RequestMapping("/order")
@Validated
public class OrderController implements IOrder {
@RequestMapping(value = "/byId",method = RequestMethod.POST)
public OrderInfo byId( @Max(value = 50) int orderId) {
return null;
}
}
Но при каждом обращении к интерфейсу выдает одну и ту же ошибку, так что этот способ бесполезен.Если кто найдет решение, подскажите, спасибо
{
"timestamp": "2018-06-24T07:09:14.235+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/order/byId"
}
Разница между @Valid и @Validated
@Valid находится в javax.validation @Validated — это инкапсуляция @Valid, которая используется механизмом проверки, предоставляемым Spring. @Validated обеспечивает функциональность группировки