SpringMVC/Spring Boot 中JSR-303的使用

原创
2018/10/08 13:58
阅读数 481

一、JSR-303的使用

    1, 在pom.xml中引入maven依赖。

        <dependency>
	      <groupId>org.springframework.boot</groupId>
	      <artifactId>spring-boot-starter-validation</artifactId>
	    </dependency>

    2,定义一个LoginVO对象用于测试

package com.example.demo.controller.vo;

import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;

import com.example.demo.annotation.IsMobile;

public class LoginVO {
	
	@NotBlank(message="用户名不能为空")
	private String username;
	
	@NotNull
	@Length(min=6,max=32,message="密码格式不对")
	private String password;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

    需要注意的是:@NotBlank注解和@NotNull注解的却别,@NotNull不会对空字符串(“”)做出判断,@NotBlank会对空字符串(“”)进行判断。

    3、定义一个全局异常捕获类,来对参数校验异常进行处理(BindException)

package com.example.demo.exception;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.demo.enums.ResultEnum;
import com.example.demo.util.Result;
import com.example.demo.util.ResultUtil;

/**
 * 全局异常处理器
 * @author dgw
 *
 */
@ControllerAdvice
public class MyExceptionHandler {
	
	private final static Logger logger=LoggerFactory.getLogger(MyExceptionHandler.class);
	
	@SuppressWarnings("rawtypes")
	@ExceptionHandler(value=Exception.class)
	@ResponseBody
	public Result handle(Exception e){
		 
		if(e instanceof MyException){
			MyException exception=(MyException)e;
			return ResultUtil.error(exception.getCode(), e.getMessage());
		}else if(e instanceof BindException){
			BindException exception=(BindException)e;
			List<ObjectError> allErrors = exception.getAllErrors();
			String defaultMessage="";
			for(ObjectError objectError:allErrors){
				defaultMessage+= objectError.getDefaultMessage()+";";
			}
			return ResultUtil.error(ResultEnum.PARAM_VALID_FAIL.getCode(),defaultMessage);
		}else{ 
			logger.error("【系统异常】 {}",e);
			return ResultUtil.error(ResultEnum.UNKOWN);
		}
		
	}

}

    4,编写测试类TestController

package com.example.demo.controller;

import javax.validation.Valid;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.controller.vo.LoginVO;

@RestController
public class TestController {
	
	
	@RequestMapping("/test")
	public String test(@Valid LoginVO loginVO){
		return "test";
	}
	
}

    5,进行测试

          (1) 用户名为空

    

        (2)用户名为“”空字符串

二、JSR-303中的一些校验注解

  • @Null 限制只能为null
  • @NotNull 限制必须不为null
  • @AssertFalse 限制必须为false
  • @AssertTrue 限制必须为true
  • @DecimalMax(value) 限制必须为一个不大于指定值的数字
  • @DecimalMin(value) 限制必须为一个不小于指定值的数字
  • @Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
  • @Future 限制必须是一个将来的日期
  • @Max(value) 限制必须为一个不大于指定值的数字
  • @Min(value) 限制必须为一个不小于指定值的数字
  • @Past 限制必须是一个过去的日期
  • @Pattern(value) 限制必须符合指定的正则表达式
  • @Size(max,min) 限制字符长度必须在min到max之间
  • @Past 验证注解的元素值(日期类型)比当前时间早
  • @NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
  • @NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
  • @Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
  • --------------------- 本文来自 走慢一点点 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/wuseyukui/article/details/81164207?utm_source=copy

三、JSP-303中自定义校验规则

    1,创建@IsMobile注解

package com.example.demo.annotation;

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.Target;

import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.NotNull;

import com.example.demo.aspect.IsMobileValidator;

@Documented
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@ReportAsSingleViolation
@NotNull
@Constraint(validatedBy = {IsMobileValidator.class })
public @interface IsMobile {
	
	boolean required() default true;//默认校验
	
	String message() default "手机号码格式错误";

	Class<?>[] groups() default { };

	Class<? extends Payload>[] payload() default { };
}

    值得注意的是必须要加上最后两个属性 groups和payload,否则会报错

   2,定义IsMobileValidator解析类

package com.example.demo.aspect;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import com.example.demo.annotation.IsMobile;
import com.example.demo.util.ValidatorUtil;

public class IsMobileValidator implements ConstraintValidator<IsMobile, String>{

	private volatile boolean required = false;
	
	@Override
	public synchronized void initialize(IsMobile constraintAnnotation) {
		required = constraintAnnotation.required();
	}

	@Override
	public boolean isValid(String value, ConstraintValidatorContext context) {
		if(required) {
			return ValidatorUtil.isMobile(value);
		}
		return true;
	}

}

    实现ConstraintValidator接口中定义的方法,initialize为初始化方法。isValid校验方法。

    3,回到LoginVO稍作修改,加上@IsMobile(message="手机格式不正确")注解

package com.example.demo.controller.vo;

import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;

import com.example.demo.annotation.IsMobile;

public class LoginVO {
	
	@NotBlank(message="用户名不能为空")
	@IsMobile(message="手机格式不正确")
	private String username;
	
	@NotNull
	@Length(min=6,max=32,message="密码格式不对")
	private String password;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

    4,再次进行测试

        (1)填写错误的用户名

        (2)填写正确的用户名

    

    校验通过了,因为功能简单,我这里就不给其它依赖到的类了。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部