Spring MVC数据校验

一般情况下,用户的输入是随意的,为了保证数据的合法性,数据验证是所有 Web 应用必须处理的问题。

Spring MVC 有以下两种方法可以验证输入:

  • 1.利用 Spring 自带的验证框架(复杂,推荐spring-boot-starter-validation)

  • 2.利用 JSR 303 实现

数据验证分为客户端验证和服务器端验证,

客户端验证主要是过滤正常用户的误操作,通过 JavaScript 代码完成。

服务器端验证是整个应用阻止非法数据的最后防线,通过在应用中编程实现。

本节使用 JSR 303 实现服务器端的数据验证

JSRJSR

是Java Specification Requests的缩写,意思是Java 规范提案,

是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。

任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。关于 JSR-303JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现,Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint

JSR 303 是 Java 为 Bean 数据合法性校验所提供的标准框架。JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证。可以通过 The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 303 查看详细内容并下载 JSR 303 Bean Validation。

JSR 303 不需要编写验证器,它定义了一套可标注在成员变量、属性方法上的校验注解,如下表所示。只针对对象属性的校验

注解 含义
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的字符串长度大小必须在指定的范围内
@Digits (integer,fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式 Hibernate Validator附加的constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的数字范围内

Spring MVC 支持 JSR 303 标准的校验框架,Spring 的 DataBinder 在进行数据绑定时,可同时调用校验框架来完成数据校验工作,(当发生错误时候触发BindException)非常简单方便。在 Spring MVC 中,可以直接通过注解驱动的方式来进行数据校验。

Spring 本身没有提供 JSR 303 的实现,Hibernate Validator 实现了 JSR 303,所以必须在项目中加入来自 Hibernate Validator 库的 jar 文件,下载地址为 The Bean Validation reference implementation. - Hibernate Validator

maven依赖

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.2.3.Final</version>
</dependency>

效验:在product类中对实体进行效验

private Integer id;
    @NotEmpty(message = "name不能为空")
    private String name;

    private BigDecimal price;
    //第一种方式:
    //@Min(value=5,message="数量最小为5")    
    //@MAx(value=100,message="数量最大为100")
    //第二种方式
    @Range(min = 5,max = 10,message = "大小必须在这个范围内")
    private Integer qty;
    private List<String> address;
    private String email;
    private String idCard;

在TeacherController中编辑controller:

@RestController
@RequestMapping("/api/teacher")
public class TeacherController {
    // 做数据效验 必须加上这个 @Valid注解 不然不显示结果
    @PostMapping
    public Integer insert(@RequestBody @Valid Product product){
        return 1;
    }
}

运行测试:

把拦截器给注释掉:运行测试一下:

如果想在控制台显示异常信息,可以debug一下看看是什么异常

异常配置:第一种方式:统一的处理

 @ExceptionHandler(BindException.class)
    public String processException(BindException e){
        BindingResult result = e.getBindingResult();
        StringBuilder sb=new StringBuilder();
        List<ObjectError> allError=result.getAllErrors();
        for (ObjectError error : allError) {
            sb.append(error.getDefaultMessage());
        }
        return sb.toString();
    }

测试运行:

第二种方式:使用自己的异常处理类 让异常信息返回json类型:

 @ExceptionHandler(Exception.class)
    public Object error( Exception e){
        int code=666;
        if(e instanceof BizException){
            BizException biz= (BizException) e;
            code=biz.getCode();
        }
        // 使用自己的异常处理
        if(e instanceof MethodArgumentNotValidException){
            StringBuilder sb = new StringBuilder();           
  List<ObjectError> allErrors = ( (MethodArgumentNotValidException) e).getBindingResult().getAllErrors();
            
            for(ObjectError error : allErrors){
                sb.append(error.getDefaultMessage());
            }
            return   ResponseDTO.error(888,sb.toString());
        }
        
        return   ResponseDTO.error(code,e.getMessage());
    }

测试访问:

正则表达式在线工具:正则表达式在线测试 | 菜鸟工具

max,min的用法

 @Min(value = 5,message = "数量最小为5")
    @Max(value = 100,message = "数量最大为100")
    private Integer qty;

测试:

邮箱验证: 必须结合非空约束

  @Email
    @NotEmpty
    private String email;

​测试

 身份证:正则表达式验证

@Pattern(regexp = "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)", message = "身份号不合法请输入18位数字")
    private String idCard;

猜你喜欢

转载自blog.csdn.net/qq_52963857/article/details/131687274