在实际工作中,得到数据后的第一步就是检验数据的正确性,如果存在录入上的问题,一般会通过注解校验,发现错误后返回给用户,但是对于一些逻辑上的错误,比如购买金额=购买数量×单价,这样的规则就很难使用注解方式进行验证了,这个时候可以使用Spring所提供的验证器(Validator)规则去验证。
  所有的验证都是要先注册验证器,不过验证器也是SpringMVC自动加载的。这里笔者下载了关于验证器所需的jar包,包括classmate-1.3.3.jar、jboss-logging-3.3.1.Final.jar、hibernate-validator-5.4.1.Final.jar和validation-api-1.1.0.Final.jar。其中,validation-api-1.1.0. Final.jar提供关于验证注解的,它只有一些定义,而没有实现;hibernate-validator-5.4.1. Final.jar是通过Hibernate检验规则的包,它的运行还依赖于classmate-1.3.3.jar和jboss-logging-3.3.1.Final.jar这两个包。我们使用Hibernate检验规则把这些包加载进来。

<!-- 验证-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>

使用JSR 303注解验证输入内容

  Spring提供了对Bean的功能校验,通过注解@Valid标明哪个Bean需要启用注解式的验证。在javax.validation.con-straints.*中定义了一系列的JSR 303规范给出的注解,在使用它们之前需要对这些注解有一定的了解,如表所示。


  代码清单15-35:交易表单

<%@ 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/annotation.do">--%>
<form action="../validate/validator.do">
<table>
<tr>
<td>产品编号:</td>
<td><input name="productId" id="productId" value="12"/></td>
</tr>
<tr>
<td>用户编号:</td>
<td><input name="userId" id="userId" value="1231"/></td>
</tr>
<tr>
<td>交易日期:</td>
<td><input name="date" id="date" value="2019-06-30"/></td>
</tr>
<tr>
<td>价格:</td>
<td><input name="price" id="price" value="12323"/></td>
</tr>
<tr>
<td>数量:</td>
<td><input name="quantity" id="quantity" value="500"/></td>
</tr>
<tr>
<td>交易金额:</td>
<td><input name="amount" id="amount" value="3523"/></td>
</tr>
<tr>
<td>用户邮件:</td>
<td><input name="email" id="email" value="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>

  代码清单15-36:表单POJO

package com.ssm.chapter15.pojo;

import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.*;
import java.util.Date; 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; @NotNull
public Long getProductId() {
return productId;
} public void setProductId(@NotNull Long productId) {
this.productId = productId;
} @NotNull
public Long getUserId() {
return userId;
} public void setUserId(@NotNull Long userId) {
this.userId = userId;
} @NotNull
public Date getDate() {
return date;
} public void setDate(@NotNull Date date) {
this.date = date;
} @NotNull
public Double getPrice() {
return price;
} public void setPrice(@NotNull Double price) {
this.price = price;
} @NotNull
public Integer getQuantity() {
return quantity;
} public void setQuantity(@NotNull Integer quantity) {
this.quantity = quantity;
} @NotNull
public Double getAmount() {
return amount;
} public void setAmount(@NotNull 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;
} @Override
public String toString() {
return "Transaction{" +
"productId=" + productId +
", userId=" + userId +
", date=" + date +
", price=" + price +
", quantity=" + quantity +
", amount=" + amount +
", email='" + email + '\'' +
", note='" + note + '\'' +
'}';
}
}

  代码清单15-37:用控制器验证表单

package com.ssm.chapter15.controller;

import com.ssm.chapter15.pojo.Transaction;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid;
import java.util.List; @Controller
@RequestMapping("/validate")
public class ValidateController { @RequestMapping("/annotation")
public ModelAndView annotationValidate(@Valid Transaction trans, Errors errors) { //是否存在错误
if (errors.hasErrors()) {
// 获取错误信息
List<FieldError> errorList = errors.getFieldErrors();
for (FieldError error : errorList) {
//打印字段错误信息
System.err.println("fied :" + error.getField() + "\t" + "msg:" + error.getDefaultMessage());
}
}
ModelAndView mv = new ModelAndView();
mv.setViewName("index");
return mv;
}
}

使用验证器

  有时候除了简单的输入格式、非空性等校验,也需要一定的业务校验,Spring提供了Validator接口来实现检验,它将在进入控制器逻辑之前对参数的合法性进行检验。
  代码清单15-39:交易验证器

package com.ssm.chapter15.validator;

import com.ssm.chapter15.pojo.Transaction;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator; public class TransactionValidator implements Validator { @Override
public boolean supports(Class<?> clazz) { //判断验证是否为Transaction,如果是则进行验证
return Transaction.class.equals(clazz);
} @Override
public void validate(Object target, Errors errors) {
Transaction trans = (Transaction) target;
// 求交易金额和价格×数量的差额
double dis = trans.getAmount() - (trans.getPrice() * trans.getQuantity());
//如果差额大于0.01,则认为业务错误
if (Math.abs(dis) > 0.01) {
// 加入错误信息
errors.rejectValue("amount", null, "交易金额和购买数量与价格不匹配");
}
}
}

  这样这个验证器就判断了是否Transaction对象,如果是才去验证后面的逻辑,那么要将它捆绑到对应的控制器中,这个时候Spring MVC提供了注解@InitBinder,后文我们会再次详细讲解@InitBinder。通过它就可以将验证器和控制器捆绑到一起,这样就能够对请求表单进行验证了。对于@InitBinder的使用还有其他的内容,这里只展示其捆绑验证器的方法。

  代码清单15-40:使用验证器验证

@InitBinder
public void initBinder(DataBinder binder) { //数据绑定器加入验证器
binder.setValidator(new TransactionValidator());
} @RequestMapping("/validator")
public ModelAndView validator(@Valid Transaction trans, Errors errors) {
//是否存在错误
if (errors.hasErrors()) {
// 获取错误信息
List<FieldError> errorList = errors.getFieldErrors();
for (FieldError error : errorList) {
// 打印字段错误信息
System.err.println("fied :" + error.getField() + "\t" + "msg:" + error.getDefaultMessage());
}
}
ModelAndView mv = new ModelAndView();
mv.setViewName("index");
return mv;
}

  比较遗憾的是,JSR 303注解方式和验证器方式不能同时使用,不过可以在使用JSR 303注解方式得到基本的检验信息后,再使用自己的方法进行验证。

Spring MVC 验证表单的更多相关文章

  1. spring mvc form表单提交乱码

    spring mvc form表单submit直接提交出现乱码.导致乱码一般是服务器端和页面之间编码不一致造成的.根据这一思路可以依次可以有以下方案. 1.jsp页面设置编码 <%@ page ...

  2. Spring MVC与表单日期提交的问题

    Spring MVC与表单日期提交的问题 spring mvc 本身并不提供日期类型的解析器,需要手工绑定, 否则会出现非法参数异常. org.springframework.beans.BeanIn ...

  3. Spring MVC 3 表单中文提交post请求和get请求乱码问题的解决方法

    在spring mvc 3.0 框架中,通过JSP页面.HTML页面以POST方式提交表单时,表单的参数传递到对应的servlet后会出现中文显示乱码的问题.解决办法可采用spring自带的过滤技术, ...

  4. spring:设置映射访问路径 或 xml配置访问路径 (spring mvc form表单)

    项目hello, 在src/main/java下面建一个目录: charpter2 一.xml配置访问路径 web.xml <web-app> <display-name>Ar ...

  5. spring mvc 接收表单 bean

    spring MVC如何接收表单bean 呢? 之前项目中MVC框架一直用struts2,所以我也就按照struts2 的思维来思考 页面loginInput.jsp: <?xml versio ...

  6. spring mvc 提交表单的例子

    1. 构建MAVEN项目,然后转换成web格式,结构图如下: 2. 通过@RequestMapping来进行配置,当输入URL时,会以此找到对应方法执行,首先调用setupForm方法,该方法主要是生 ...

  7. Spring Boot 验证表单

    在实际工作中,得到数据后的第一步就是验证数据的正确性,如果存在录入上的问题,一般会通过注解校验,发现错误后返回给用户,但是对于逻辑上的错误,很难使用注解方式进行验证了,这个使用可以使用Spring所提 ...

  8. 使用Spring MVC 的表单控制器SimpleFormController

    以注册过程为例,我们可能会选择继承AbstractController来实现表单的显示,继承AbstractCommandController来实现表单的处理 ,这样是可行的,但必须要维护两个控制器 ...

  9. spring mvc防止表单重复提交的代码片段

    1.定义一个token接口 package com.bigbigrain.token; import java.lang.annotation.Documented; import java.lang ...

随机推荐

  1. grep命令的or,and,not操作的例子

    在Linux的grep命令中如何使用OR,AND,NOT操作符呢? 其实,在grep命令中,有OR和NOT操作符的等价选项,但是并没有grep AND这种操作符.不过呢,可以使用patterns来模拟 ...

  2. Ubuntu 16.04LTS 安装和配置Bochs

    环境:VMWare14+Ubuntu16.04 安装Bochs2.6.9 1.去官网下载 下载 bochs-2.6.9.tar.gz 2.安装一系列的包 因为Bochs 需要在 X11 环境下运行,因 ...

  3. BZOJ 3625:小朋友和二叉树 多项式开根+多项式求逆+生成函数

    生成函数这个东西太好用了~ code: #include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s&q ...

  4. Web API系列(二) Filter的使用以及执行顺序

    在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想 ...

  5. 数据库(以MySQL为例)

    一.数据库简介 数据库就是数据的仓库,用来按照特定的结构去组织和管理数据,有了数据库可以更加方便.便捷的操作需要保存的数据 不管是什么数据库,最终都是将数据保存到硬盘中,只是存储的格式不同于文本文件 ...

  6. 搞清楚ourhdr.h是什么及运行第一个UNIX C程序

    好多人开始学:UNIX 环境高级编程这本书时:看到书里面说的头文件ourhdr.h而找不到她在哪里:而且无法开始继续学习:其实这个就是系统的内核标准头文件: 而她的位置在:/usr/include/u ...

  7. GO语言html模板

    模板 一个模板是一个字符串或一个文件,里面包含了一个或多个由双花括号包含的{{action}}对象.大部分的字符串只是按面值打印,但是对于actions部分将触发其它的行为.每个actions都包含了 ...

  8. java.io.FileNotFoundException: D:\e (拒绝访问。)

    这是因为访问的文件地址是文件夹而不是,具体的文件,把路径改为具体的文件就可以了. 参考文章:https://blog.csdn.net/w405722907/article/details/78610 ...

  9. 【转】npm 安装express npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE

    npm  安装 express  出现 npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATUREnpm ERR! errno UNABLE_TO_VERIFY_LEA ...

  10. Qt Creater-特殊注释TODO,FIXME

    简述 TODO: + 说明: 如果代码中有该标识,说明在标识处有功能代码待编写,待实现的功能在说明中会简略说明. FIXME: + 说明: 如果代码中有该标识,说明标识处代码需要修正,甚至代码是错误的 ...