内置约束:
(1)对外接口:
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
@RestController
@RequestMapping("/common")
public class HelloRestController {
@RequestMapping(value = "/validate")
public Result save(@Validated UserVo user) {
Result result = new Result();
result.setCode(200);
result.setMessage(JSONObject.toJSON(user).toString());
return result;
}
}
(2)对UserVo类字段使用校验注解
import java.util.Date;
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import org.springframework.format.annotation.DateTimeFormat;
public class UserVo {
@Size(min=2, max=30)
private String name;
//自定义错误信息
@NotEmpty(message = "自定义错误信息,Email不能为空")
@Email
private String email;
@NotNull
@Min(18) @Max(100)
private Integer age;
@NotNull
private Gender gender;
@DateTimeFormat(pattern="MM/dd/yyyy")
@NotNull @Past
private Date birthday;
// 自定义规则注解
@PhoneValidation
private String phone;
...//省略get set 方法
}
(3)自定义注解:PhoneValidation
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Documented
@Constraint(validatedBy = PhoneValidationValidator.class) //指定真正实现校验规则的类
@Target( { METHOD, FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface PhoneValidation {
String message() default "不是正确的手机号码。"; //可使用properties配置
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@interface List {
PhoneValidation[] value();
}
}
(3)实际校验规则
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PhoneValidationValidator implements ConstraintValidator<PhoneValidation, String>{
private static final Pattern PHONE_PATTERN = Pattern.compile(
"^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))\\d{8}$"
);
@Override
public void initialize(PhoneValidation constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if ( value == null || value.length() == 0 ) {
return true;
}
Matcher m = PHONE_PATTERN.matcher(value);
return m.matches();
}
}
(4)写一个全局的 Validation 异常捕获类
package com.example.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class BindExceptionHanlder {
private static final Logger logger = LoggerFactory.getLogger(BindExceptionHanlder.class);
@ExceptionHandler(BindException.class)
public Result handleBindException(BindException ex) {
/**
* ex.getFieldError():
* Get the first error associated with a field, if any.(获取第一个错误)
*
* ex.getAllErrors():
* Get all errors, both global and field ones(获取全部错误)
*
*/
FieldError fieldError = ex.getFieldError();
StringBuilder sb = new StringBuilder();
//fieldError.getField()//字段名
//fieldError.getRejectedValue()//值
//fieldError.getDefaultMessage()//异常信息
sb.append(fieldError.getField()).append("=\"")
.append(fieldError.getRejectedValue()).append("\"")
.append(fieldError.getDefaultMessage());
logger.info(sb.toString());
//返回校验异常
Result result = new Result();
result.setCode(400);
result.setMessage(sb.toString());
return result;
}
}
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
注意:
@ControllerAdvice,@RestControllerAdvice:注解定义全局异常处理类 ;@ExceptionHandler 注解声明异常处理方法。
如果使用,但返回的是 json,则需在处理异常的方法中加上@ResponseBody 注解。与 @Controller VS @RestController 类似。