当业务需要参数校验的时候,可以直接在controller 写入校验逻辑
参数校验经验: 用户业务,前端页面校验、服务端参数 校验
管理后台:前端校验,服务端可以放开
javax.validation包提供了常见参数的校验注解,如果常见注解不能满足可以使用
@Pattern 注解 使用正则表达式校验
校验注解:
这是javax.validation包中的 主要包括上述的几个注解
注解 描述
@AssertFalse 被注释的元素必须为 false
@AssertTrue 同@AssertFalse
@DecimalMax 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin
同DecimalMax
@Digits 被注释的元素是数字
@Future 将来的日期
@Max 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Min 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@NotNull 不能是Null
@Null
元素是Null
@Past 被注释的元素必须是一个过去的日期
@Pattern 被注释的元素必须符合指定的正则表达式
@Szie 被注释的元素
mvc 接收参数的基本形式
1.1 @PathVariable
略:
1.2 @RequestParam
直接在@RequestParam 后添加校验注解
并在类上添加 @Validated 注解
@Validated
public class UserController extends AbstractController {
@PostMapping("id_card/add")
@ApiOperation(value = "用户身份证信息提交")
Resp<Boolean> userAddInfo(@Pattern(regexp ="^[\\u4e00-\\u9fa5]{2,10}$",message = "请输入中文姓名") String username, @Pattern(regexp = "^[0-9]{18}$", message = "身份证号只支持数字,18位") @RequestParam("id_card") String id_card) {
User user = new User();
user.setId(userAccountService.userInfoByUuid(getCurrentUserUuid()).getId());
user.setIdCard(id_card);
user.setUsername(username);
EntityUtil.prevModify(user);
if (userAccountService.userIdCradInfoAdd(user)) {
return Resp.success(Boolean.TRUE);
}
return Resp.customFail("419", "用户身份证信息添加失败");
}
}
1.3@requestbody
如果业务逻辑复杂,参数较多情况下
使用@requestBody 接收参数,在实体中写入校验规则
Bean Validation为JavaBean提供了相应的API来给我们做参数的验证。通过Bean Validation比如@NotNull @Pattern等方法 可以方便的集成数据校验逻辑。
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.Pattern;
/**
* @version :
* @date :2019-08-14
*/
@Data
public class BankCardForm {
@ApiModelProperty(value = "用户姓名", notes = "用户姓名中文")
@Pattern(regexp = "^[\\u4e00-\\u9fa5]{2,10}$", message = "姓名只支持中文 2-10个汉字")
private String username;
@ApiModelProperty(value = "用户身份证号码", notes = "用户身份证号码")
@Pattern(regexp = "^[0-9]{18}$", message = "身份证号只支持数字,18位")
private String idCard;
@ApiModelProperty(value = "开户行名称", notes = "开户行")
@Pattern(regexp = "^[\\u4e00-\\u9fa5]{2,20}$", message = "开户行只支持中文 2-20个汉字")
private String bankName;
@ApiModelProperty(value = "银行卡号", notes = "银行卡号")
@Pattern(regexp = "^[0-9]{15,20}$", message = "银行卡号只支持数字,15-20位")
private String cardNo;
}
如果参数校验未通过
会抛出异常
javax.validation.ConstraintViolationException: null
接下来
我们在拦截器中统一处理异常 给前端接口
@RestControllerAdvice
@Slf4j
public class ExceptionHandlerAdvice {
@ExceptionHandler(value = Exception.class)
public Result defaultException(Exception ex) {
//TODO 默认异常需要处理
log.error("默认异常需要处理", ex);
if (ex instanceof ResultCode) {
return R.error(((ResultCode) ex).getCode(), ((ResultCode) ex).getMsg());
}
if (ex instanceof UnexpectedTypeException) {
return R.error(451, ex.getMessage());
}
if(ex instanceof CrmException){
CrmException crmException = (CrmException)ex;
return R.error(crmException.getCode(), crmException.getMsg());
}
if (ex instanceof ConstraintViolationException) {
return R.error(452, ex.getMessage());
}
return Result.error(SystemCodeEnum.SYSTEM_ERROR);
}
自定义注解
自定义校验注解
定义@ListNotHasNull注解, 用于校验 List 集合中是否有null 元素
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
//此处指定了注解的实现类为ListNotHasNullValidatorImpl
@Constraint(validatedBy = ListNotHasNullValidatorImpl.class)
public @interface ListNotHasNull {
/**
* 添加value属性,可以作为校验时的条件,若不需要,可去掉此处定义
*/
int value() default 0;
String message() default "List集合中不能含有null元素";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* 定义List,为了让Bean的一个属性上可以添加多套规则
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@interface List {
ListNotHasNull[] value();
}
}
注意:message、groups、payload属性都需要定义在参数校验注解中不能缺省
注解实现类
该类需要实现ConstraintValidator
import org.springframework.stereotype.Service;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;
public class ListNotHasNullValidatorImpl implements ConstraintValidator<ListNotHasNull, List> {
private int value;
@Override
public void initialize(ListNotHasNull constraintAnnotation) {
//传入value 值,可以在校验中使用
this.value = constraintAnnotation.value();
}
public boolean isValid(List list, ConstraintValidatorContext constraintValidatorContext) {
for (Object object : list) {
if (object == null) {
//如果List集合中含有Null元素,校验失败
return false;
}
}
return true;
}
}
然后我们就能在之前的例子中使用该注解了:
@NotEmpty
@ListNotHasNull
private List<@Valid UserInfo> parents;
参考:
注解失效的情况
检查pom文件引用
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.2.Final</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.0-alpha1</version>
</dependency>
再检查idea 配置
参考资料:
参考资料:
https://www.jianshu.com/p/89a675b7c900