文章目录
- 前言
- java-校验注解使用归纳
- 1. 概述
- 2. 引入依赖
- 3. 手动抓取校验错误信息示例
- 4. 自定义校验注解编写示例
- 5. 统一配置校验错误信息示例
前言
如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!
java-校验注解使用归纳
1. 概述
Hibernate Validator 是一个基于 Java Bean 标准和注解的验证框架,它是 Hibernate 社区为 Java Bean 验证定义的一套实现。它是 Java Bean Validation(JSR 380)规范的参考实现。
Hibernate Validator 提供了一组注解,用于在 Java 对象上定义验证规则,并提供了验证器来校验对象是否符合指定的规则。通过使用这些注解和验证器,您可以在应用程序中方便地执行数据验证和验证错误的处理,确保数据的合法性和完整性,从而提高应用程序的数据质量和安全性。
2. 引入依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.4.Final</version>
</dependency>
3. 手动抓取校验错误信息示例
校验VO:
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotEmpty;
import java.math.BigDecimal;
/**
* @author yangzhenyu
* @version 1.0
* @description:
* @date 2023/7/21 14:50
*/
@Data
@ToString
public class TestFrom {
@ApiModelProperty("金额")
@DecimalMin(value = "0.009", message = "大于0")
@Digits(message = "格式错误", integer = Integer.MAX_VALUE, fraction = 2)
@NotNull(message = "不能为空")
private BigDecimal money;
@ApiModelProperty("id")
@NotEmpty(message = "ID不能为空")
private String id;
}
controller:
@ApiOperation(value = "原生校验测试",notes = "原生校验测试")
@RequestMapping(value = "/test/v1/checkTest",method = RequestMethod.POST)
public TestVo checkTest(@Valid @RequestBody TestFrom searchParam, BindingResult result){
if (result.hasErrors()) {
List<String> collect = result.getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.toList());
return TestVo.builder().errorMsg(String.join(",", collect)).build();
}
return TestVo.builder().build();
}
在接受参数的地方加入BindingResult result参数,当校验注解校验住的时候,result.hasErrors()为true
测试:
输入:
{
"id": "",
"money": 1.12
}
输出:
输入:
{
"id": "",
"money": "0"
}
输出:
4. 自定义校验注解编写示例
示例判断传入日期格式是否正确:
/**
* @author yangzhenyu
* @version 1.0
* @description: 注意只接受 日期字段以字符串的接受方式 使用: @DateCheck(message = "操作日期结束时间格式不正确",patternDatetime = "yyyy-MM-dd")
* @date 2023/7/21 17:40
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(
validatedBy = {DateCheckValidator.class}
)
@Documented
public @interface DateCheck {
String message() default "时间格式不正确";
String patternDatetime() default "yyyy-MM-dd HH:mm:ss";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
import org.example.validation.annotation.DateCheck;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
* @author yangzhenyu
* @version 1.0
* @description:
* @date 2023/7/21 17:40
*/
public class DateCheckValidator implements ConstraintValidator<DateCheck, Object> {
private String patternDatetime;
@Override
public void initialize(DateCheck dataCheck) {
patternDatetime = dataCheck.patternDatetime();
}
public Boolean timeValidator(String time){
try {
SimpleDateFormat formatter = new SimpleDateFormat(patternDatetime);
formatter.parse(time);
return Boolean.TRUE;
}catch (ParseException e){
return Boolean.FALSE;
}
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
String time = String.valueOf(o);
if (timeValidator(time)){
return Boolean.TRUE;
}else {
return Boolean.FALSE;
}
}
}
在vo上字段上加上刚刚我们加上的注解
@Data
@ToString
public class TestFrom {
@ApiModelProperty("金额")
@DecimalMin(value = "0.009", message = "大于0")
@Digits(message = "格式错误", integer = Integer.MAX_VALUE, fraction = 2)
@NotNull(message = "不能为空")
private BigDecimal money;
@ApiModelProperty("id")
@NotEmpty(message = "ID不能为空")
private String id;
@ApiModelProperty("创建日期")
@DateCheck(message = "创建日期格式不正确",patternDatetime = "yyyy-MM-dd")
private String createDate;
}
5. 统一配置校验错误信息示例
import org.example.vo.TestVo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
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.ResponseBody;
import javax.servlet.http.HttpSession;
/**
* @author yangzhenyu
* @version 1.0
* @description:
* @date 2023/7/24 10:33
*/
@ControllerAdvice
@ConditionalOnExpression("${config.exception.switch:true} == true")
public class MyControllerAdvice {
/**
* 全局传参校验异常抓取
* */
@ResponseBody
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public TestVo bingException(MethodArgumentNotValidException e, HttpSession session){
return TestVo.builder().errorMsg(e.getBindingResult().getFieldError().getDefaultMessage()).build();
}
}
将刚刚我们设置的手动获取校验错误信息的BindingResult 类型的参数去掉:
@ApiOperation(value = "原生校验测试",notes = "原生校验测试")
@RequestMapping(value = "/test/v1/checkTest",method = RequestMethod.POST)
public TestVo checkTest(@Valid @RequestBody TestFrom searchParam){
return TestVo.builder().build();
}
测试:
输入:
{
"createDate": "string",
"id": "",
"money": 0
}
输出:
输入:
{
"createDate": "string",
"id": "1",
"money": 0
}
输出:
输入:
{
"createDate": "2023-07-23",
"id": "1",
"money": 0
}
输出:
输入:
{
"createDate": "2023-07-23",
"id": "1",
"money": 1
}