【4】Spring Boot系列之Validation

内置约束:
在这里插入图片描述

(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 类似。

参考:https://blog.csdn.net/hry2015/article/details/79572713

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值