SpringMVC后台控制端校验-表单验证深度分析与实战优化

前言

在实战开发中,数据校验也是十分重要的环节之一,数据校验大体分为三部分:

  • 前端校验
  • 后端校验
  • 数据库校验

本文讲解如何在后端控制端进行表单校验的工作

案例实现

在进行项目开发的时候,前端(jquery-validate),后端,数据库都要进行相关的数据校验,springmvc也支持校验,但是没有进行具体的实现,所以要添加hibernate的依赖来完成校验

第一步:添加依赖

pom.xml

XML 复制代码
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>

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

第二步:创建表单提交页面和实体类

实体类Transaction

在相关的实体类中,根据需要加入校验规则,它支持email,日期等内置校验规则

java 复制代码
public class Transaction {
    // 产品编号
    @NotNull // 不能为空
    private Long productId;

    // 用户编号
    @NotNull // 不能为空
    private Long userId;

    // 交易日期
    @Future // 只能是将来的日期
    @DateTimeFormat(pattern = "yyyy-MM-dd") // 日期格式化转换
    @NotNull // 不能为空
    private Date date;

    // 价格
    @NotNull // 不能为空
    @DecimalMin(value = "0.1") // 最小值0.1元
    private Double price;

    // 数量
    @Min(1) // 最小值为1
    @Max(100) // 最大值
    @NotNull // 不能为空
    private Integer quantity;

    // 交易金额
    @NotNull // 不能为空
    @DecimalMax("500000.00") // 最大金额为5万元
    @DecimalMin("1.00") // 最小交易金额1元
    private Double amount;

    // 邮件
    @Pattern(// 正则式
            regexp = "^([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)*@"
                    + "([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\.][A-Za-z]{2,3}([\\.][A-Za-z]{2})?$",
            // 自定义消息提示
            message = "不符合邮件格式")
    private String email;

    // 备注
    @Size(min = 0, max = 256) // 0到255个字符
    private String note;

    public Long getProductId() {
        return productId;
    }

    public void setProductId(Long productId) {
        this.productId = productId;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public Integer getQuantity() {
        return quantity;
    }

    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }

    public Double getAmount() {
        return amount;
    }

    public void setAmount(Double amount) {
        this.amount = amount;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

}

JSP页面validate.jsp

html 复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>validate</title>
    </head>
    <body>
        
        <form action = "/validate/vali.do">
        <!-- 
        <form action = "./validate/validator.do">
        -->
            <table>
                <tr>
                    <td>产品编号:</td>
                    <td><input name="productId" id="productId"/></td>
                </tr>
                <tr>
                    <td>用户编号:</td>
                    <td><input name="userId" id="userId"/></td>
                </tr>
                <tr>
                    <td>交易日期:</td>
                    <td><input name="date" id="date"/></td>
                </tr>
                <tr>
                    <td>价格:</td>
                    <td><input name="price" id="price"/></td>
                </tr>
                <tr>
                    <td>数量:</td>
                    <td><input name="quantity" id="quantity"/> </td>
                </tr>
                <tr>
                    <td>交易金额:</td>
                    <td><input name="amount" id="amount"/></td>
                </tr>
                <tr>
                    <td>用户邮件:</td>
                    <td><input name="email" id="email"/></td>
                </tr>
                <tr>
                    <td>备注:</td>
                    <td><textarea id="note"  name="note" cols="20" rows="5"></textarea></td>
                </tr>
                <tr><td colspan="2" align="right"> <input type="submit" value="提交"/> </tr>
            </table>
        <form>
    </body>
</html>

第三步:编写校验器

TransactionValidator

java 复制代码
package com.csx.validate;

import com.csx.entity.Transaction;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

public class TransactionValidator implements Validator {
    //表示判断是否是指定被校验的类,如例子当中的Transaction,如果是,会返回true,继续进行校验
    @Override
    public boolean supports(Class<?> aClass) {
        //如果是Transaction类,返回true,进行验证
        return Transaction.class.equals(aClass);
    }

    //编写校验规则
    @Override
    public void validate(Object obj, Errors errors) {
        Transaction tran = (Transaction) obj;
        //求总金额和单价及数量的差额
        double dis = tran.getAmount() - (tran.getQuantity() * tran.getPrice());

        if (Math.abs(dis) > 0.01) {
            errors.rejectValue("amount",null,"交易金额有误,请检查");
        }


    }
}

第四步:编写控制层

TransactionController

java 复制代码
@RequestMapping("/validate")
@Controller
public class TransactionController {

    @RequestMapping("/vali")
    public ModelAndView addTran(@Valid Transaction tran, Errors errors) {
        //判断是否有校验错误信息
        if (errors.hasErrors()) {
            List<FieldError> list = errors.getFieldErrors();
            for (FieldError f : list) {
                System.out.println("error Filed:" + f.getField() + ",errorMsg:" + f.getDefaultMessage());
            }
        }
        return new ModelAndView("index");

    }


    //为当前控制器开启验证
    @InitBinder
    public void initBinder(DataBinder binder) {
        binder.setValidator(new TransactionValidator());
    }

}
  1. 使用hasErrors判断是否有校验错误
  2. 如果有,使用getFieldErrors()获取错误集合,
  3. 使用getField()获取错误字段,
  4. 使用getDefaultMessage获取错误信息
  5. 如果违反了定义的校验规则,则会报错

测试

表单提交页面

故意将日期和交易金额填写错误,并提交


后台控制台显示数据错误提示

  • 箭头指向的第一个,是date,即日期格式错误
  • 箭头指向的第二个,表示交易金额错误,为我们自定义的提示信息

总结

数据校验在实际开发中很重要,而仅仅做了前端校验,还是不安全的,因此我们还可以进行后台的数据校验。

相关推荐
楠寻寻2 天前
Spring、SpringMVC、SpringBoot、Mybatis小结
spring boot·spring·mybatis·springmvc
ModelBulider3 天前
十四、SpringMVC的执行流程
java·开发语言·后端·spring·springmvc
阑梦清川8 天前
SpringMVC案例学习(一)--计算器设计&&登录页面设计
java·登录页面·springmvc·案例计算器
B1nna9 天前
SpringMVC学习记录(三)之响应数据
java·学习·json·springmvc·jsp
ModelBulider9 天前
九、HttpMessageConverter
java·开发语言·后端·spring·springmvc
皮不卡球秋11 天前
SpringMVC
java·spring boot·spring·springmvc·springboot
灰色孤星A20 天前
后台管理系统的通用权限解决方案(十)如何自定义SpringMVC的参数解析器
java·springmvc·springboot·参数解析器
一朵忽明忽暗的云25 天前
【SSM-Day5】SpringMVC
spring·springmvc
Onlooker1291 个月前
SpringMVC6-SpringMVC的视图
springmvc
云和数据.ChenGuang1 个月前
第二章 SpringMVC
springmvc