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

前言

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

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

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

 案例实现

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

 第一步:添加依赖

pom.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,日期等内置校验规则

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

<%@ 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

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

@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,即日期格式错误
  • 箭头指向的第二个,表示交易金额错误,为我们自定义的提示信息 

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/892854.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【华为】静态路由配置

1.配置接入层&#xff1a; LSW1&#xff08;LSW3同理&#xff09;: vlan batch 10 20 in g0/0/1 port link-type ac port default vlan 10 in g0/0/2 port link-type ac port default vlan 20 in g0/0/24 port link-type tr port tr allow-pass vlan 10 202.配置汇聚层&#xf…

v853扬声器调试

文章目录 1、前言2、环境介绍3、修改设备树4、使用tinymix测试扬声器 1、前言 本文记录v853下的扬声器调试。 2、环境介绍 硬件&#xff1a;韦东山v853 aicit板卡 软件&#xff1a;v853 tina sdk 3、修改设备树 扬声器使用的是v853内置的audio codec&#xff0c;原理图如…

进程的属性

一、进程状态 CPU执行进程代码不是把进程代码执行完毕&#xff0c;才开始执行下一个&#xff0c;而是给每一个进程预分配一个时间片&#xff0c;基于时间片&#xff0c;进行调度轮转。 并行和并发 并行: 多个进程在多个CPU下分别&#xff0c;同时进行运行&#xff0c;这称之…

设计小白必看!一文教你区分原型图和UI图

产品设计过程中&#xff0c;产品经理或UI设计师常常需要在不同的设计阶段产出不同的原型图和UI图。初入职场的产品小白或UI小白很容易将原型图和UI图混淆&#xff0c;不能完全区分它们各自的作用&#xff0c;从而影响了设计流程的效率和效果。本文将详细解析原型图与UI图的定义…

【DS】哈希表,哈希桶的实现

目录 哈希概念哈希冲突哈希函数负载因子哈希冲突的解决闭散列开散列 哈希表闭散列的实现哈希表的结构哈希函数构造函数查找插入删除 哈希表开散列的实现哈希表的结构查找插入删除 哈希表的表长建议是素数 平衡二叉树的学习中&#xff0c;学习及模拟实现了AVL树和红黑树&#xf…

uni-app写的微信小程序如何体积太大如何处理

方法一&#xff1a;对主包进行分包处理&#xff0c;将使用url: /pages/components/equipment/equipment跳转页面的全部拆分为分包&#xff0c;如url: /pagesS/components/equipment/equipment 在pages.json中添加 "subPackages": [{ "root"…

STM32项目实战:基于STM32F4的智能灯光控制系统(LVGL),附项目教程/源码

《智能灯光控制系统_STM32F4》项目完整文档、项目源码&#xff0c;点击下方链接免费领取。 项目资料领取https://s.c1ns.cn/jjQK7 STM32项目实战之“智能灯光控制系统”&#xff08;基于STM32F4&#xff09; 今天小编来分享一个《智能灯光控制系统》的项目案例&#xff0c;硬件…

如何批量下载采集淘宝图片?3个方法可以帮助你

如何批量下载采集淘宝图片&#xff1f;在现代电子商务的背景下&#xff0c;淘宝作为中国最大的在线购物平台之一&#xff0c;承载了数以亿计的商品和信息。对于从事电商运营、市场推广或网络营销的人员而言&#xff0c;采集淘宝图片已经成为日常工作中的重要任务。这不仅是为了…

Jenkins pipeline语法笔记

Jenkins pipeline 简介Jenkins Pipeline 优势DSL 是什么 pipeline支持两种语法&#xff1a;声明式pipeline语法&#xff1a;Pipelineagent Pipeline 声明式语法DeclarativeenvironmentoptionsparameterstriggerstoolsinputwhenParallel Pipeline Scripted语法创建一个简单的 Pi…

(38)MATLAB分析带噪信号的频谱

文章目录 前言一、MATLAB仿真代码二、仿真结果画图总结 前言 本文给出带噪信号的时域和频域分析&#xff0c;指出频域分析在处理带噪信号时的优势。 首先使用MATLAB生成一段信号&#xff0c;并在信号上叠加高斯白噪声得到带噪信号&#xff0c;然后对带噪信号对其进行FFT变换&…

数据结构:跳表

数据结构&#xff1a;跳表 跳表实现类架构构造函数析构函数查找插入删除 总代码 跳表 在传统的链表中&#xff0c;不论单链表还是双链表&#xff0c;查询时都要O(N)的时间复杂度&#xff0c;就算是一个有序链表&#xff0c;由于无法像数组一样定址&#xff0c;无法进行二分查找…

学习最新vue20.17.0-事件处理

vue中文官网事件处理 | Vue.js (vuejs.org) 我在官网基础上,添加些代码,方便初学者学习,能够快速理解官网内容,掌握自己所需要的知识,以便节省宝贵的时间。 事件处理 监听事件 我们可以使用 v-on 指令 (简写为 @) 来监听 DOM 事件,并在事件触发时执行对应的 JavaScript…

Anaconda3与PyCharm安装配置

参考文章 Anaconda3与PyCharm安装配置保姆教程 参照上面文章&#xff0c;安装好Anaconda3和PyCharm环境 下面重点记录下环境配置 1&#xff0c;在window系统菜单中选择Anaconda Prompt&#xff0c;而不是Anaconda Powershell Prompt 2, 打开Anaconda Prompt&#xff0c;输…

[网络基础]——什么是IP路由,路由优先级,度量值详解

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;网络通信基础TCP/IP专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年10月14日15点23分 路由器扮演着至关重要的角色&#xff0c;它不仅负责将数据包从源地址转发到目的地址&#xff0c;还…

wsl1升级到wsl2步骤

1、进入到windows功能界面&#xff08;winr&#xff1a;输入cmd&#xff0c;到界面里面输出control&#xff09; 这几个选项勾选上&#xff0c;然后自动重启电脑 2、下载WSL2内核安装包 前往此链接&#xff0c;然后点击下图的下载链接&#xff0c;下载这个更新包后用管理员权…

美畅物联丨剖析 GB/T 28181 与 GB 35114:视频汇聚领域的关键协议

我们在使用畅联云平台进行视频汇聚时&#xff0c;经常会用的GB/T 28181协议&#xff0c;前面我们写了关于GB/T 28181的相关介绍&#xff0c;​ 详见《畅联云平台&#xff5c;关于GB28181你了解多少&#xff1f;》。 ​最近也有朋友向我们咨询GB 35114协议与GB/T 28181有什么不同…

详细分析Redisson分布式锁中的renewExpiration()方法

目录 一、Redisson分布式锁的续期 整体分析 具体步骤和逻辑分析 为什么需要递归调用&#xff1f; 定时任务的生命周期&#xff1f; 一、Redisson分布式锁的续期 Redisson是一个基于Redis的Java分布式锁实现。它允许多个进程或线程之间安全地共享资源。为了实现这一点&…

闯关leetcode——118. Pascal‘s Triangle

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/pascals-triangle/description/ 内容 Given an integer numRows, return the first numRows of Pascal’s triangle. In Pascal’s triangle, each number is the sum of the two numbers direct…

2.Java--入门程序

一、开发Java程序 步骤&#xff1a; 1.编写代码 其中第一行的HelloWorld叫类名&#xff0c;下面的框架叫main()方法&#xff0c; 类名要和文件名一致&#xff0c; 2.编译代码 用Javac进行编译&#xff0c;将编写的代码保存之后&#xff0c;打开WindowsR输入cmd 用cd文件夹…

SPP与SPPF的区别?Anchor based和Anchor free的区别?

SPP与SPPF的区别&#xff1f; spp是何凯明提出来的&#xff0c;名为空间金子塔&#xff0c;有效避免了对图像区域的裁剪、缩放操作导致的图像失真等问题。 解决了卷积神经网络对图相关重复特征提取的问题&#xff0c;大大提高了产生候选框的速度&#xff0c;且节省了计算成本。…