SpringMVC(8)------ 实用技术(3)表单校验

image-20211005172028601

表单校验规则

  • 长度: 例如用户名长度,评论字符数量
  • 非法字符: 例如用户名组成
  • 数据格式:例如Email格式、I p地址格式
  • 边界值: 例如转账金额上限,年龄上下限
  • 重复性:例如用户名是否重复

表单校验框架

  • JSR (Java Specification Requests):Java规范提案

    • 303:提供bean属性相关校验规则
  • JCP (Java Community Process) : Java社区

  • Hibernate框架中包含一套独立的校验框架hibernate-validator

    image-20211005172623705

image-20211005184944482
image-20211005185003082
image-20211005185032388

image-20211005192446174

测试代码

  • pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.yy</groupId>
          <artifactId>springmvc_validator</artifactId>
          <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
    
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <dependencies>
          <!-- servlet3.0规范的坐标 -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <!--jsp坐标-->
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.1</version>
                <scope>provided</scope>
            </dependency>
            <!--spring的坐标-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.1.9.RELEASE</version>
            </dependency>
            <!--springmvc的坐标-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.1.9.RELEASE</version>
            </dependency>
    
            <!--导入校验的jsr303规范-->
            <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>2.0.1.Final</version>
            </dependency>
            <!--导入校验框架实现技术-->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>6.1.0.Final</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <!--设置插件-->
            <plugins>
                <!--具体的插件配置-->
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.1</version>
                    <configuration>
                        <port>80</port>
                        <path>/</path>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    
    
  • web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
             version="3.1">
    
        <filter>
            <filter-name>characterEncodingFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>characterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
        <servlet>
            <servlet-name>DispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath*:spring-mvc.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
    </web-app>
    
    
  • spring-mvc.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    
        <context:component-scan base-package="com.itheima"/>
    
        <mvc:annotation-driven />
    
    </beans>
    
  • addempliyee.jsp

    <%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
    <html>
    <head>
        <title>添加员工-用于演示表单验证</title>
    </head>
    <body>
        <form action="/addemployee" method="post">
                                                               <%--页面使用${}获取后台传递的校验信息--%>
            员工姓名:<input type="text" name="name"><span style="color:red">${name}</span><br/>
            员工年龄:<input type="text" name="age"><span style="color:red"></span><br/>
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    
  • employeeControlle.java核心

import com.yy.controller.groups.GroupA;
import com.yy.domain.Employee;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.validation.Valid;
import java.util.List;

@Controller
public class EmployeeController {

    @RequestMapping(value = "/addemployee")
    public String addEmployee(@Valid Employee employee, Errors errors, Model m){
        if(errors.hasErrors()){
            List<FieldError> fieldErrors = errors.getFieldErrors();
            System.out.println(fieldErrors.size());
            for(FieldError error : fieldErrors){
                System.out.println(error.getField());
                System.out.println(error.getDefaultMessage());
                m.addAttribute(error.getField(),error.getDefaultMessage());
            }
            return "addemployee.jsp";
        }
        return "success.jsp";
    }

    
}

  • Employee.java

    import com.yy.controller.groups.GroupA;
    import org.hibernate.validator.constraints.Range;
    
    import javax.validation.Valid;
    import javax.validation.constraints.*;
    
    public class Employee{
        //设定校验器,设置校验不通过对应的消息,设定所参与的校验组
        @NotBlank(message = "姓名不能为空")
        private String name;//员工姓名
    
        
        private Integer age;//员工年龄
    
    ......
    }
    
    
  • success.jsp,成功后跳转的页面

    <%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
    <h1>数据添加成功</h1>
    
    

多规则校验

测试代码:

可以对年龄和名字进行校验了,但是不用去修改controller,只需要在实体类Employee中去提交下面的代码,和jsp里面添加一个el表达式,如下

Employee.java

import com.yy.controller.groups.GroupA;
import org.hibernate.validator.constraints.Range;

import javax.validation.Valid;
import javax.validation.constraints.*;

public class Employee{
    //设定校验器,设置校验不通过对应的消息,设定所参与的校验组
    @NotBlank(message = "姓名不能为空")
    private String name;//员工姓名

    //一个属性可以添加多个校验器
    @NotNull(message = "请输入您的年龄")
    @Max(value = 60,message = "年龄最大值不允许超过60岁")
    @Min(value = 18,message = "年龄最小值不允许低于18岁")
    private Integer age;//员工年龄
......
}

addemployee.jsp

<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
<html>
<head>
    <title>添加员工-用于演示表单验证</title>
</head>
<body>
    <form action="/addemployee" method="post">
                                                           <%--页面使用${}获取后台传递的校验信息--%>
        员工姓名:<input type="text" name="name"><span style="color:red">${name}</span><br/>
        员工年龄:<input type="text" name="age"><span style="color:red">${age}</span><br/>
       
        <input type="submit" value="提交">
    </form>
</body>
</html>

嵌套校验

image-20211005192538020

与之前的校验就多了两个东西,

第一在Employee.java这个实体类里面添加了address这个引用数据类型,address的校验在Address.java实体类中进行校验

第二便是:取出来的消息对应的key的名称你不是一个对象封装的属性,是按照对象名.属性名的形式做了一个整体

addemployee.jsp

<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
<html>
<head>
    <title>添加员工-用于演示表单验证</title>
</head>
<body>
    <form action="/addemployee" method="post">
                                                           <%--页面使用${}获取后台传递的校验信息--%>
        员工姓名:<input type="text" name="name"><span style="color:red">${name}</span><br/>
        员工年龄:<input type="text" name="age"><span style="color:red">${age}</span><br/>
        <%--注意,引用类型的校验未通过信息不是通过对象进行封装的,直接使用对象名.属性名的格式作为整体属性字符串进行保存的,和使用者的属性传递方式有关,不具有通用性,仅适用于本案例--%>
        省:<input type="text" name="address.provinceName"><span style="color:red">${requestScope['address.provinceName']}</span><br/>
        <input type="submit" value="提交">
    </form>
</body>
</html>

Employee.java在这里多了一个引用类型address

import com.yy.controller.groups.GroupA;
import org.hibernate.validator.constraints.Range;

import javax.validation.Valid;
import javax.validation.constraints.*;

public class Employee{
    //设定校验器,设置校验不通过对应的消息,设定所参与的校验组
    @NotBlank(message = "姓名不能为空")
    private String name;//员工姓名

    //一个属性可以添加多个校验器
    @NotNull(message = "请输入您的年龄")
    @Max(value = 60,message = "年龄最大值不允许超过60岁")
    @Min(value = 18,message = "年龄最小值不允许低于18岁")
    private Integer age;//员工年龄

    //实体类中的引用类型通过标注@Valid注解,设定开启当前引用类型字段中的属性参与校验
    @Valid
    private Address address;
.......
}

Address.java

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
//嵌套校验的实体中,对每个属性正常添加校验规则即可
public class Address {
    @NotBlank(message = "请输入省份名称")
    private String provinceName;//省份名称

    @NotBlank(message = "请输入城市名称")
    private String cityName;//城市名称

    @NotBlank(message = "请输入详细地址")
    private String detail;//详细住址

    @NotBlank(message = "请输入邮政编码")
    @Size(max = 6,min = 6,message = "邮政编码由6位组成")
    private String zipCode;//邮政编码

   .....
}

EmployeeController.java

import com.yy.controller.groups.GroupA;
import com.yy.domain.Employee;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.validation.Valid;
import java.util.List;

@Controller
public class EmployeeController {

    @RequestMapping(value = "/addemployee")
    public String addEmployee(@Valid Employee employee, Errors errors, Model m){
        if(errors.hasErrors()){
            List<FieldError> fieldErrors = errors.getFieldErrors();
            System.out.println(fieldErrors.size());
            for(FieldError error : fieldErrors){
                System.out.println(error.getField());
                System.out.println(error.getDefaultMessage());
                m.addAttribute(error.getField(),error.getDefaultMessage());
            }
            return "addemployee.jsp";
        }
        return "success.jsp";
    }
}

分组校验

控制这一次参与校验,下一次不参与校验

将其分为若干个组,分别在每一次校验哪一个组

image-20211005192654024

首先需要添加一个分组的接口,如下:

package com.yy.controller.groups;
//用于设定分组校验中的组名,当前接口仅提供字节码,用于识别
public interface GroupA {
}

其次修改Employee.java实体类,为里面的属性设置分组

import com.yy.controller.groups.GroupA;
import org.hibernate.validator.constraints.Range;

import javax.validation.Valid;
import javax.validation.constraints.*;

public class Employee{
    //设定校验器,设置校验不通过对应的消息,设定所参与的校验组
    @NotBlank(message = "姓名不能为空",groups = {GroupA.class})
    private String name;//员工姓名

    //一个属性可以添加多个校验器
    @NotNull(message = "请输入您的年龄",groups = {GroupA.class})
    @Max(value = 60,message = "年龄最大值不允许超过60岁")
    @Min(value = 18,message = "年龄最小值不允许低于18岁")
    private Integer age;//员工年龄

    //实体类中的引用类型通过标注@Valid注解,设定开启当前引用类型字段中的属性参与校验
    @Valid
    private Address address;
 ....
}

最后修改EmployeeController,将@Valid修改为@Validated({GroupA.class})

import com.yy.controller.groups.GroupA;
import com.yy.domain.Employee;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.validation.Valid;
import java.util.List;

@Controller
public class EmployeeController {

    @RequestMapping(value = "/addemployee")
    public String addEmployee(@Validated({GroupA.class}) Employee employee, Errors errors, Model m){
        if(errors.hasErrors()){
            List<FieldError> fieldErrors = errors.getFieldErrors();
            System.out.println(fieldErrors.size());
            for(FieldError error : fieldErrors){
                System.out.println(error.getField());
                System.out.println(error.getDefaultMessage());
                m.addAttribute(error.getField(),error.getDefaultMessage());
            }
            return "addemployee.jsp";
        }
        return "success.jsp";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

?abc!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值