public enum ResultCode {
/**操作成功**/
RESULT_SUCCESS_CODE(200,"操作成功"),
/**操作失败**/
RESULT_ERROR_CODE(500,"操作失败");
private final int code;
private final String message;
ResultCode(int code, String message){
this.code = code;
this.message = message;
}
public int getCode() { return code; }
public String getMessage() { return message; }
}
public class ResultData<T> {
/** 结果状态 ,具体状态码参见ResultData.java*/
private int code;
/**响应消息**/
private String message;
/**响应数据**/
private T data;
/**接口请求时间**/
private long timestamp ;
public ResultData (){
this.timestamp = System.currentTimeMillis();
}
public static <T> ResultData<T> success(String message) {
ResultData<T> resultData = new ResultData<>();
resultData.setCode(ResultCode.RESULT_SUCCESS_CODE.getCode());
resultData.setMessage(message);
return resultData;
}
public static <T> ResultData<T> success() {
ResultData<T> resultData = new ResultData<>();
resultData.setCode(ResultCode.RESULT_SUCCESS_CODE.getCode());
resultData.setMessage(ResultCode.RESULT_SUCCESS_CODE.getMessage());
return resultData;
}
public static <T> ResultData<T> success(T data) {
ResultData<T> resultData = new ResultData<>();
resultData.setCode(ResultCode.RESULT_SUCCESS_CODE.getCode());
resultData.setMessage(ResultCode.RESULT_SUCCESS_CODE.getMessage());
resultData.setData(data);
return resultData;
}
public static <T> ResultData<T> fail(String message) {
ResultData<T> resultData = new ResultData<>();
resultData.setCode(ResultCode.RESULT_ERROR_CODE.getCode());
resultData.setMessage(message);
return resultData;
}
public static <T> ResultData<T> fail(int code, String message) {
ResultData<T> resultData = new ResultData<>();
resultData.setCode(code);
resultData.setMessage(message);
return resultData;
}
public static <T>ResultData<T> fail() {
ResultData<T> resultData = new ResultData<>();
resultData.setCode(ResultCode.RESULT_ERROR_CODE.getCode());
resultData.setMessage(ResultCode.RESULT_ERROR_CODE.getMessage());
return resultData;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
}
@Data
public class User {
@NotNull(groups = ValidationGroups.update.class, message = "id不能为空")
@Null(groups = ValidationGroups.insert.class)
private String id;
@Length(min = 11,max = 11,message = "手机号格式不正确")
private String phone;
@NotBlank(message = "名字为必填项")
private String name;
@Email(message = "请填写正确的邮箱地址")
private String email;
@EnumValue(strValues = {"0","1"}, message="性别只能是0或者1")
private String sex;
@NotNull(message = "年龄不能为空")
private Integer age;
@Valid // 嵌套验证必须用@Valid
private Dog dog;
}
@Data
public class Dog {
@NotNull(message = "id不能为空")
private Integer id;
@NotBlank(message = "name不能为空")
private String name;
}
自定义分组
public class ValidationGroups {
public interface insert{};
public interface update{};
}
自定义注解规则
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {EnumValueValidator.class})
public @interface EnumValue {
// 默认错误消息
String message() default "必须为指定值";
String[] strValues() default {};
int[] intValues() default {};
// 分组
Class<?>[] groups() default {};
// 负载
Class<? extends Payload>[] payload() default {};
// 指定多个时使用
@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@interface List {
EnumValue[] value();
}
}
public class EnumValueValidator implements ConstraintValidator<EnumValue, Object> {
private String[] strValues;
private int[] intValues;
@Override
public void initialize(EnumValue constraintAnnotation) {
strValues = constraintAnnotation.strValues();
intValues = constraintAnnotation.intValues();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (value instanceof String) {
for (String s : strValues) {
if (s.equals(value)) {
return true;
}
}
} else if (value instanceof Integer) {
for (int s : intValues) {
if (s == ((Integer) value).intValue()) {
return true;
}
}
}
return false;
}
}
异常增强类
@RestControllerAdvice
public class WebExceptionHandler extends RuntimeException{
/** requestBody 实体类形式接受参数验证 **/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResultData validationErrorHandler(MethodArgumentNotValidException ex) {
String message = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
return ResultData.fail(message);
}
/** Form-data 实体类形式接受参数验证 **/
@ExceptionHandler(BindException.class)
@ResponseBody
public ResultData validationErrorHandler(BindException ex) {
String message = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
return ResultData.fail(message);
}
/** RequestParam 接受参数验证 **/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ResultData validationErrorHandler(ConstraintViolationException ex) {
String message = ex.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
return ResultData.fail(message);
}
/** hibernate-valid实体类形式接受参数验证失败 **/
@ExceptionHandler(Exception.class)
@ResponseBody
public ResultData exceptionHandler(Exception ex) {
return ResultData.fail(ex.getMessage());
}
}
Controller
@RestController
//@Validated
public class ValidController {
/** RequestBody **/
@PostMapping("/test1")
public String test1(@Validated @RequestBody User user){
System.out.println(user);
return "test1 valid success";
}
/** RequestBody **/
@PostMapping("/test2")
public String test2(@Valid @RequestBody User user){
System.out.println(user);
return "test1 valid success";
}
/** 单参数校验 **/
@PostMapping("/test3")
public String test3(@Email String email){
return "email valid success";
}
@PostMapping("/add")
public String add(@Validated({ValidationGroups.insert.class}) @RequestBody User user){
return "add valid success";
}
@PostMapping("/update")
public String update(@Validated({ValidationGroups.update.class}) @RequestBody User user){
return "update valid success";
}
}
@Validated和@Valid的区别
1.分组区别
@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制
@Valid:没有分组的功能。
2. 注解地方
@Validated:可以用在类型、方法和方法参数上。
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {
Class<?>[] value() default {};
}
@Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上
@Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
public @interface Valid {
}
嵌套验证
@Validated不能用于成员属性(字段)上,所有不能提供嵌套验证的功能。