目錄
- 使用validator
- 項(xiàng)目實(shí)戰(zhàn)
- 在全局校驗(yàn)中增加校驗(yàn)異常
- 自定義參數(shù)注解
使用validator
- javax.validation的一系列注解可以幫我們完成參數(shù)校驗(yàn),免去繁瑣的串行校驗(yàn)
- pom引入
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- hibernate validator-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.0.Final</version>
</dependency>
項(xiàng)目實(shí)戰(zhàn)
@PostMapping("/save/valid")
public RspDTO save(@RequestBody @Validated UserDTO userDTO) {
userService.save(userDTO);
return RspDTO.success();
}
public class UserDTO implements Serializable {
private static final long serialVersionUID = 1L;
/*** 用戶ID*/
@NotNull(message = "用戶id不能為空")
private Long userId;
/** 用戶名*/
@NotBlank(message = "用戶名不能為空")
@Length(max = 20, message = "用戶名不能超過20個(gè)字符")
@Pattern(regexp = "^[\\u4E00-\\u9FA5A-Za-z0-9\\*]*$", message = "用戶昵稱限制:最多20字符量承,包含文字宛乃、字母和數(shù)字")
private String username;
/** 手機(jī)號*/
@NotBlank(message = "手機(jī)號不能為空")
@Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手機(jī)號格式有誤")
private String mobile;
/**性別*/
private String sex;
/** 郵箱*/
@NotBlank(message = "聯(lián)系郵箱不能為空")
@Email(message = "郵箱格式不對")
private String email;
/** 密碼*/
private String password;
/*** 創(chuàng)建時(shí)間 */
@Future(message = "時(shí)間必須是將來時(shí)間")
private Date createTime;
}
在全局校驗(yàn)中增加校驗(yàn)異常
@RestControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
private static int DUPLICATE_KEY_CODE = 1001;
private static int PARAM_FAIL_CODE = 1002;
private static int VALIDATION_CODE = 1003;
/**
* 處理自定義異常
*/
@ExceptionHandler(BizException.class)
public RspDTO handleRRException(BizException e) {
logger.error(e.getMessage(), e);
return new RspDTO(e.getCode(), e.getMessage());
}
/**
* 方法參數(shù)校驗(yàn)
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public RspDTO handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
logger.error(e.getMessage(), e);
return new RspDTO(PARAM_FAIL_CODE, e.getBindingResult().getFieldError().getDefaultMessage());
}
/**
* ValidationException
*/
@ExceptionHandler(ValidationException.class)
public RspDTO handleValidationException(ValidationException e) {
logger.error(e.getMessage(), e);
return new RspDTO(VALIDATION_CODE, e.getCause().getMessage());
}
/**
* ConstraintViolationException
*/
@ExceptionHandler(ConstraintViolationException.class)
public RspDTO handleConstraintViolationException(ConstraintViolationException e) {
logger.error(e.getMessage(), e);
return new RspDTO(PARAM_FAIL_CODE, e.getMessage());
}
@ExceptionHandler(NoHandlerFoundException.class)
public RspDTO handlerNoFoundException(Exception e) {
logger.error(e.getMessage(), e);
return new RspDTO(404, "路徑不存在,請檢查路徑是否正確");
}
@ExceptionHandler(DuplicateKeyException.class)
public RspDTO handleDuplicateKeyException(DuplicateKeyException e) {
logger.error(e.getMessage(), e);
return new RspDTO(DUPLICATE_KEY_CODE, "數(shù)據(jù)重復(fù)谅海,請檢查后提交");
}
@ExceptionHandler(Exception.class)
public RspDTO handleException(Exception e) {
logger.error(e.getMessage(), e);
return new RspDTO(500, "系統(tǒng)繁忙,請稍后再試");
}
}
自定義參數(shù)注解
- message 定制化的提示信息陷舅,主要是從ValidationMessages.properties里提取,也可以依據(jù)實(shí)際情況進(jìn)行定制; groups 這里主要進(jìn)行將validator進(jìn)行分類,不同的類group中會(huì)執(zhí)行不同的validator操作; payload 主要是針對bean的馆铁,使用不多。
@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = IdentityCardNumberValidator.class)
public @interface IdentityCardNumber {
String message() default "身份證號碼不合法";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class IdentityCardNumberValidator implements ConstraintValidator<IdentityCardNumber, Object> {
@Override
public void initialize(IdentityCardNumber identityCardNumber) {
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
// 需要自己定義業(yè)務(wù)實(shí)現(xiàn)
return IdCardValidatorUtils.isValidate18Idcard(o.toString());
}
}
@NotBlank(message = "身份證號不能為空")
@IdentityCardNumber(message = "身份證信息有誤,請核對后提交")
private String clientCardNo;
使用groups的校驗(yàn)
- UserDTO在更新時(shí)候要校驗(yàn)userId,在保存的時(shí)候不需要校驗(yàn)userId,在兩種情況下都要校驗(yàn)username,那就用上groups了
- 定義Create, Update
import javax.validation.groups.Default;
public interface Create extends Default {
}
import javax.validation.groups.Default;
public interface Update extends Default{
}
- 在需要使用的地方添加更新操作锅睛, 這里表示Upate時(shí)會(huì)校驗(yàn)參數(shù)
@PostMapping("/update/groups")
public RspDTO update(@RequestBody @Validated(Update.class) UserDTO userDTO) {
userService.updateById(userDTO);
return RspDTO.success();
}
@NotNull(message = "用戶id不能為空", groups = Update.class)
private Long userId;
參考文章