SpringMVC数据校验

使用SpringMVC时配合hibernate-validate进行参数的合法性校验,验证客户输入的数据是否合法,能节省一定的代码量。

1. 搭建Web工程并引入hibernate-validate依赖

  
      org.hibernate.validator
      hibernate-validator
      6.1.2.Final
  
  
     org.glassfish
     jakarta.el
     3.0.3
  
  
     org.hibernate.validator
     hibernate-validator-cdi
     6.1.2.Final
  

2. SpringMVC.xml配置

    
    
    
    
        
        
        
        
    

    
        
        
            
                classpath:CustomValidationMessages
            
        
        
        
        
        
    

自定义校验信息提示文件CustomValidationMessages.properties

emp.empno=\u96C7\u5458\u7F16\u53F7\u53EA\u80FD\u4E3A\u56DB\u4F4D\u6570\u5B57\u7EC4\u6210  //雇员编号只能为四位数字组成
emp.ename=\u96C7\u5458\u59D3\u540D\u53EA\u80FD\u7531\u6570\u5B57\u3001\u5B57\u6BCD\u3001\u4E0B\u5212\u7EBF\u3001\u957F\u77ED\u5FC5\u987B\u57286-10\u4F4D\u4E4B\u95F4  //雇员编号只能为四位数字组成
emp.job=\u804C\u4F4D\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A  //职位名称不能为空
emp.email=\u975E\u6CD5\u90AE\u7BB1 //非法邮箱

3. 使用校验注解标注在属性上(DTO)



*每个注解都有message属性,该属性用于填写校验失败时的异常描述信息,当校验失败时可以获取对应的message属性值。

4. Spring MVC 数据校验

  • Spring 4.0 拥有自己独立的数据校验框架,同时支持 JSR 303 标准的校验框架。
  • Spring 在进行数据绑定时,可同时调用校验框架完成数据校验工作。在 Spring MVC 中,可直接通过注解驱动的方式进行数据校验
  • Spring 的 LocalValidatorFactroyBean 既实现了 Spring 的 Validator 接口,也实现了 JSR 303 的 Validator 接口。只要在 Spring 容器中定义了一个 LocalValidatorFactoryBean,即可将其注入到需要数据校验的 Bean 中。
  • Spring 本身并没有提供 JSR303 的实现,所以必须将 JSR303 的实现者的 jar 包放到类路径下。

  • 会默认装配好一个 LocalValidatorFactoryBean,通过在处理方法的入参上标注 @valid 注解即可让 Spring MVC 在完成数据绑定后执行数据校验的工作
  • Spring MVC 是通过对处理方法签名的规约来保存校验结果的:前一个表单/命令对象的校验结果保存到随后的入参中,这个保存校验结果的入参必须是 BindingResult 或 Errors 类型,这两个类都位于 org.springframework.validation 包中

  • 需校验的 Bean 对象和其绑定结果对象或错误对象时成对出现的,它们之间不允许声明其他的入参
  • Errors 接口提供了获取错误信息的方法,如 getErrorCount() 或 getFieldErrors(String field)
  • BindingResult 扩展了 Errors 接口


    image.png

5. 使用@Validated/@Valid注解开启对参数的校验

  • @Validated注解表示开启Spring的校验机制,支持分组校验,声明在入参上。
  • @Valid注解表示开启Hibernate的校验机制,不支持分组校验,声明在入参上。
  • 在DTO后面紧跟BindingResult对象,那么当参数不符合时,能通过该对象直接获取不符合校验的message描述信息。
  • 若使用了@Validated/@Valid注解开启校验,但DTO后面没有紧跟BindingResult对象,那么当参数不符合时,将直接返回400 Bad Request状态码。

6. 在页面上显示错误(需要引入SpringMVC表单标签库)

  • Spring MVC 除了会将表单/命令对象的校验结果保存到对应的 BindingResult 或 Errors 对象中外,还会将所有校验结果保存到 “隐含模型”
  • 即使处理方法的签名中没有对应于表单/命令对象的结果入参,校验结果也会保存在 “隐含对象” 中。
  • 隐含模型中的所有数据最终将通过 HttpServletRequest 的属性列表暴露给 JSP 视图对象,因此在 JSP 中可以获取错误信息
  • 在 JSP 页面上可通过 显示错误消息

7. 示例

public class Emp {
    @Max(value = 9999L)
    @Min(value = 1000)
    private int empno;

    @Pattern(regexp = "[0-9A-Za-z_]{6,10}", message = "雇员姓名只能由数字、字母、下划线、长短必须在6-10位之间")
    private String ename;

    @NotBlank(message = "工作不能为空")
    private String job;

    private int mgr;

    private Date hiredate;

    @Email(message = "非法邮箱!")
    private String email;

    private double sal;

    private double comm;

    private Dept dept;

    ...
    @RequestMapping("/adduser")
    public void addUser(@Validated Emp emp, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List errors = bindingResult.getAllErrors();
            for (ObjectError objectError : errors) {
                System.out.println(objectError.getDefaultMessage());
            }
        }
        System.out.println(emp.getHiredate());
    }

8. 提示消息的国际化

上述例子代码中,我们自定义错误消息,使用了message 属性来自定义消息描述,但是这样做我们就失去了国际化的功能,消息国际化我们可以通过编写国际化配置文件来实现

当使用 Spring MVC 标签显示错误消息时, Spring MVC 会查看 WEB 上下文是否装配了对应的国际化消息,如果没有,则显示默认的错误消息,否则使用国际化消息。

配置校验器以及国际化配置文件

    
    
    
    
        
        
        
        
    

    
        
        
            
                classpath:CustomValidationMessages
            
        
        
        
        
        
    

自定义校验信息提示文件CustomValidationMessages.properties

emp.empno=\u96C7\u5458\u7F16\u53F7\u53EA\u80FD\u4E3A\u56DB\u4F4D\u6570\u5B57\u7EC4\u6210  //雇员编号只能为四位数字组成
emp.ename=\u96C7\u5458\u59D3\u540D\u53EA\u80FD\u7531\u6570\u5B57\u3001\u5B57\u6BCD\u3001\u4E0B\u5212\u7EBF\u3001\u957F\u77ED\u5FC5\u987B\u57286-10\u4F4D\u4E4B\u95F4  //雇员编号只能为四位数字组成
emp.job=\u804C\u4F4D\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A  //职位名称不能为空
emp.email=\u975E\u6CD5\u90AE\u7BB1 //非法邮箱

校验目标类

public class Emp {
    @Max(value = 9999L)
    @Min(value = 1000)
    private int empno;
    @Pattern(regexp = "[0-9A-Za-z_]{6,10}", message = "{emp.ename}")
    private String ename;
    @NotBlank(message = "{emp.job}")
    private String job;
    private int mgr;
    private Date hiredate;
    @Email(message = "{emp.email}")
    private String email;
    private double sal;
    private double comm;
    private Dept dept;// 一对一
    ...

9.分组校验

9.1. 什么是分组校验?

校验规则是在pojo 制定的,而同一个pojo可以被多个Controller使用,此时会有问题,即:不同的Controller方法对同一个pojo进行校验,此时这些校验信息是共享在这不同的Controller方法中,但是实际上每个Controller方法可能需要不同的校验,在这种情况下,就需要使用分组校验来解决这种问题。
通俗的讲,一个pojo中有很多属性,controller中的方法1可能只需要校验pojo中的属性1,controller中的方法2只需要校验pojo中的属性2,但是pojo中的校验注解有很多,怎样才能使方法1只校验属性1,方法二只校验属性2呢?就需要用分组校验来解决了。

9.2. 定义分组

定义分组

就是定义空的接口,接口类只作为这个分组标识来使用,看下面的用法,就知道其意义何在了

9.3. 使用分组

image.png

9.4. controller方法

在这个方法中,那么就只会校验Emp这个pojo中有Group1.class这个分组的校验注解,而不会在校验其他的


image.png

10 扩展知识

使用SpringMVC表单标签库来参数校验https://www.cnblogs.com/hemou/p/12356175.html
SpringMVC表单标签库https://www.jianshu.com/p/b1f2d50b671c
SpringMVC_数据校验https://blog.csdn.net/qq_40794973/article/details/97967016

你可能感兴趣的:(SpringMVC数据校验)