前言
在实战开发中,数据校验也是十分重要的环节之一,数据校验大体分为三部分:
- 前端校验
- 后端校验
- 数据库校验
本文讲解如何在后端控制端进行表单校验的工作
案例实现
在进行项目开发的时候,前端(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());
}
}
- 使用hasErrors判断是否有校验错误
- 如果有,使用getFieldErrors()获取错误集合,
- 使用getField()获取错误字段,
- 使用getDefaultMessage获取错误信息
- 如果违反了定义的校验规则,则会报错
测试
表单提交页面
故意将日期和交易金额填写错误,并提交
后台控制台显示数据错误提示
- 箭头指向的第一个,是date,即日期格式错误
- 箭头指向的第二个,表示交易金额错误,为我们自定义的提示信息
总结
数据校验在实际开发中很重要,而仅仅做了前端校验,还是不安全的,因此我们还可以进行后台的数据校验。