引入依赖
org.springframework.boot spring-boot-starter-validation2.5.5
实体类字段注解
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableId
private Long brandId;
@NotBlank(message = "品牌名必须提交")
private String name;
@URL(message = "logo必须上一个合法的URL地址")
private String logo;
private String descript;
@TableLogic(value = "1",delval = "0")
private Integer showStatus;
//自定义校验规则
@Pattern(regexp="/^[a-zA-Z]$/",message="检索首字母必须上一个字母")
private String firstLetter;
//最小值为0
@Min(value=0,message = "排序最小大于等于0")
private Integer sort;
}
controller 层 校验 要加上@Valid 校验才会生效,BindingResult 获取校验后的异常信息
@RequestMapping("/save")
public R save(@Valid @RequestBody BrandEntity brand, BindingResult result) {
if (result.hasErrors()) {
Map map = new HashMap<>();
result.getFieldErrors().forEach((item) -> {
String defaultMessage = item.getDefaultMessage();
String field = item.getField();
map.put(field, defaultMessage);
});
return R.error(400, "提交数据不合法").put("data", map);
} else {
brandService.save(brand);
return R.ok();
}
}
可以写一个异常处理类,异常集中处理,写异常类统一校验之后controller层就不需要写校验处理了,该怎么写就怎么写就行
package com.jzy.gulimall.product.exception;
import com.jzy.common.exception.BizCodeEnume;
import com.jzy.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
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 org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
//@ResponseBody
//@ControllerAdvice(basePackages = "com.jzy.gulimall.product.controller")
@RestControllerAdvice
@Slf4j
public class GulimallExceptionControllerAdvice {
@ExceptionHandler(value= MethodArgumentNotValidException.class)
public R handleException(MethodArgumentNotValidException e){
log.error("数据校验出现问题「」,异常类型",e.getMessage(),e.getClass());
Map map=new HashMap<>();
BindingResult bindingResult = e.getBindingResult();
bindingResult.getFieldErrors().forEach((item)->{
String field = item.getField();
String defaultMessage = item.getDefaultMessage();
map.put(field,defaultMessage);
});
return R.error(BizCodeEnume.VALID_EXCEPTION.getCode(),BizCodeEnume.VALID_EXCEPTION.getMsg()).put("data",map);
}
@ExceptionHandler(value= Throwable.class)
public R handleException(Throwable throwable){
return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
}
}
分组校验:
有的字段新增必须为空,而修改必须不能为空所有要进行校验分组(自增id)
只需改变实体类和control层注解:
实体类:
分组实体类:
package com.jzy.gulimall.product.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.jzy.common.valid.AddGroup;
import com.jzy.common.valid.UpdateGroup;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
import javax.validation.constraints.*;
import java.io.Serializable;
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull(message = "修改必须制定品牌id",groups = {UpdateGroup.class})
@Null(message="新增不能制定品牌id",groups = {AddGroup.class})
@TableId
private Long brandId;
@NotNull(message = "品牌名不能为空",groups = {AddGroup.class})
private String name;
@NotNull(message = "品牌logo地址不能为空",groups = {AddGroup.class})
@URL(message = "logo必须上一个合法的URL地址",groups = {AddGroup.class,UpdateGroup.class})
private String logo;
@NotNull(message = "介绍不能为空",groups = {AddGroup.class})
private String descript;
// @Pattern(regexp="/^[0-1]$/",message="显示状态只能上1或者0",groups = {AddGroup.class,UpdateGroup.class})
@TableLogic(value = "1",delval = "0")
private Integer showStatus;
@NotNull(message = "检索首字母不能为空",groups = {AddGroup.class})
@Pattern(regexp="/^[a-zA-Z]$/",message="检索首字母必须上一个字母",groups = {AddGroup.class,UpdateGroup.class})
private String firstLetter;
@Min(value=0,message = "排序最小大于等于0")
private Integer sort;
}
controller:
在参数括号中加上@Validated注解并制定分组
@RequestMapping("/save")
public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand) {
brandService.save(brand);
return R.ok();
}
@RequestMapping("/update")
public R update(@Validated({UpdateGroup.class}) @RequestBody BrandEntity brand) {
brandService.updateById(brand);
return R.ok();
}
分组实体类:
这里的分组实体类只需要创建一个类做区分就行
自定义校验器
1.创建一个校验注解
注解对应的类
package com.jzy.common.valid;
import javax.validation.Constraint;
import java.lang.annotation.documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@documented
@Constraint(validatedBy = { ListValueConstraintValidator.class })
@Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.ANNOTATION_TYPE, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE_USE})
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
public @interface ListValue {
java.lang.String message() default "{com.jzy.common.valid.ListValue.message}";
java.lang.Class>[] groups() default {};
java.lang.Class extends javax.validation.Payload>[] payload() default {};
int[] values() default {};
}
2.编写一个自定义校验器ConstrainValidator
package com.jzy.common.valid; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.HashSet; import java.util.Set; public class ListValueConstraintValidator implements ConstraintValidator{ private Set set=new HashSet<>(); @Override public void initialize(ListValue constraintAnnotation) { int[] values = constraintAnnotation.values(); if (values != null && values.length != 0){ for (int value : values) { set.add(value); } } } @Override public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) { return set.contains(integer); } }
3.关联自定义的校验器和自定义的注解



