validation自动校验参数

hashmap

记录一次springboot整合validation参数校验踩过的坑

  • pom文件引入相关的基本依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--核心依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  • 根据网上的提示引入validation依赖
1
2
3
4
5
	<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
  • 注意这里引入这个依赖之后各种坑,postman传参接收不到,一开始不论传什么,设置条件都会全部出来。。。
  • 后来debug之后才发现是传的参数根本没进来,经过一番源码debug,并没有发现什么不对劲的地方,就是到了判断参数的时候,参数为空.

更换 validation依赖 如下

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  • 既然整合那就整合优雅一点,让代码看上去不那么繁琐,如果整合之后的代码量更多,更复杂,那就失去整合的意义了,不如if()else{} 一个一个判断,所以就有下面全局异常处理

设置全局异常返回类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

@ControllerAdvice
public class BadRequestExceptionHandler {

private static final Logger logger = LoggerFactory.getLogger(BadRequestExceptionHandler.class);

/**
* 校验错误拦截处理
* ExceptionHandler 注解必须要表明自己想要处理的异常
* @ResponseStatus(HttpStatus.BAD_REQUEST)。是为了想返回指定的错误代码
* 比如:200 400 500
* @param exception 错误信息集合
* @return 错误信息
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<Object> validationBodyException(MethodArgumentNotValidException exception){
BindingResult result = exception.getBindingResult();
if (result.hasErrors()) {
List<ObjectError> errors = result.getAllErrors();
errors.forEach(p ->{
FieldError fieldError = (FieldError) p;
logger.error("Data check failure : object{"+fieldError.getObjectName()+"},field{"+fieldError.getField()+
"},errorMessage{"+fieldError.getDefaultMessage()+"}");
});
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("请填写正确信息");
}

/**
* 参数类型转换错误
*
* @param exception 错误
* @return 错误信息
*/
@ExceptionHandler(HttpMessageConversionException.class)
public Resp parameterTypeException(HttpMessageConversionException exception){
logger.error(exception.getCause().getLocalizedMessage());
return Resp.fail("类型转换错误");

}


}
  • Controller 层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
	
@Controller
@Validated
@RequestMapping("/v1")
public class TestValidation {
private static Logger logger = LoggerFactory.getLogger(TestValidation.class);

@RequestMapping(value = "/validation",method = RequestMethod.POST)
@ResponseBody
public Resp validation(@Valid @RequestBody PersionTest persionTest){
logger.info(persionTest.toString);
return Resp.success("lcc");
}
}
  • PO写法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

import java.io.Serializable;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.Range;

@Setter
@Getter
@ToString
public class PersionTest implements Serializable {

@Length(min=3, max=20, message="name长度只能在6-20之间")
@NotEmpty(message="用户名不能为空")
private String name;

@Range(min = 18,max = 100,message = "必须在18-100之间")
private int age;

@Min(value = 1, message = "min Value is above zero")
@Max(value = 10, message = "最大值不超过10")
private Integer Clas_p;

}

*以下列举部分常用的validation相关的注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

注解 作用
@NotNull 值不能为空
@Null 值必须为空
@Pattern(regex=) 字符串必须匹配正则表达式
@Size(min, max) 集合元素的数量必须在min和max之间
@CreditCardNumber(ignoreNonDigitCharacters=) 字符串必须是信用卡号,按找美国的标准验证
@Email 字符串必须是Email地址
@Length(min, max) 检查字符串的长度
@NotBlank 字符串不能为空串
@NotEmpty 字符串不能为null, 集合必须有元素
@Range(min, max) 数字必须大于min, 小于max
@SafeHtml 字符串必须是安全的html
@URL 字符串必须是合法的URL
@AssertFalse 值必须是false
@AssertTrue 值必须是true
@DecimalMax(value=, inclusive=) 值必须小于等于(inclusive=true)/小于(inclusive=false)属性指定的值,也可以注释在字符串类型的属性上。
@DecimalMin(value=, inclusive=) 值必须大于等于(inclusive=true)/小于(inclusive=false)属性指定的值,也可以注释在字符串类型的属性上。
@Digist(integer=,fraction=) 数字格式检查。integer指定整数部分的最大长度,fraction指定小数部分的最大长度
@Future 时间必须是未来的
@Past 事件必须是过去的
@Max(value=) 值必须小于等于value指定的值。不能注解在字符串类型属性上。
@Min(value=) 值必须小于等于value指定的值。不能注解在字符串类型属性上。
坚持原创技术分享,您的支持将鼓励我继续创作!