在Spring MVC中提供了验证器可以进行服务端校验,所有的验证都必须先注册校验器,不过校验器也是Spring MVC自动加载的,在使用Spring MVC校验器之前首先要下载相关的jar包,下面是我的一些jar所对应的maven依赖:

 <!-- 验证器所需的包 -->
<dependency>
<groupId>com.fasterxml</groupId>
<artifactId>classmate</artifactId>
<version>1.4.0</version>
</dependency> <dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.3.2.Final</version>
</dependency> <dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency> <dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>

其中:

  • validator-api-*:提供关于验证注解的;
  • hibernate-validator-*:是通过hibernate校验规则的包,他还要依赖classmate和jboss-logging这两个包;

Spring MVC中有两种校验方式,一种是使用JSR 303注解验证输入内容,另一种是使用校验器。

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

spring提供了对bean的校验功能,通过注解@Valid表明对哪个Bean需要启用注解式校验。这种方式可以用来对字段进行非空、合法性等的校验,它还提供了一些校验规则约束:

Bean Validate中提供的约束有以下几种:

Hibernate中也提供了一些约束:

具体内容可参考这个网站:

https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/

二、使用校验器

有时候除了合法性校验之外,还需要进行一些业务逻辑校验,比如用户名不能重复等,这就需要使用校验器来完成。使用校验器需要进行两步操作:

1、完成校验器:SpringMVC提供了一个validator接口,我们只要实现这个接口中的方法即可;

2、绑定到控制器:创建完了校验器之后要告诉容器需要校验哪个控制器,所以需要将校验器和控制器绑定,绑定的方法很简单,就是在控制器中写一个方法并使用注解@InitBinder即可。

下面结合这两种校验方式写一个例子说明。

三 、实例

1、创建一个表单

这个表单用来输入一些信息

<form id="paramForm" action="<%=basePath%>customer/addCustomer"
method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="cusName" id="input_cus_name"
value=""></td>
</tr>
<tr>
<td>用户年龄:</td>
<td><input type="text" name="cusAge" id="input_cus_age"
value=""></td>
</tr>
<tr>
<td>用户性别:</td>
<td><label for="input_cus_sex1">男</label><input type="radio"
name="cusSex" id="input_cus_sex1" value="1"><label
for="input_cus_sex0">女</label><input type="radio" name="cusSex"
id="input_cus_sex0" value="0"></td>
</tr>
<tr>
<td>手机号码:</td>
<td><input type="text" name="cusPhone" id="input_cus_phone"
value=""></td>
</tr>
<tr>
<td>邮箱地址:</td>
<td><input type="text" name="cusEmail" id="input_cus_email"
value=""></td>
</tr>
<tr>
<td></td>
<td style="text-align: right;"><input type="submit"
value="提交" id="addCustomer"></td>
</tr>
</table>
</form>

因为向后台传的是个pojo对象,所以name名称要和pojo对象属性保持一致。

2、创建表单中数据对应的pojo,并使用JSR 303校验字段

public class Customer {
private Integer cusId; @NonNull
@Pattern(regexp
= "^([a-zA-Z]*[0-9_-]*$)", message = "只能包含字母、数字、下划线,且不能以数字或下划线开头")
@Size(min = 8, max = 128)
private String cusName; @NotNull
@Min(
18)
@Max(40)
private Integer cusAge; @NotNull
private Integer cusSex; @NotNull
@Size(min
= 6, max = 11)
@Pattern(regexp = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$", message = "请输入正确的手机号")
private String cusPhone; @NotNull
@Size(min
= 10, max = 20)
@Pattern(regexp = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$", message = "请输入正确的电子邮箱")
private String cusEmail; public Integer getCusId() {
return cusId;
} public void setCusId(Integer cusId) {
this.cusId = cusId;
} public String getCusName() {
return cusName;
} public void setCusName(String cusName) {
this.cusName = cusName == null ? null : cusName.trim();
} public Integer getCusAge() {
return cusAge;
} public void setCusAge(Integer cusAge) {
this.cusAge = cusAge;
} public Integer getCusSex() {
return cusSex;
} public void setCusSex(Integer cusSex) {
this.cusSex = cusSex;
} public String getCusPhone() {
return cusPhone;
} public void setCusPhone(String cusPhone) {
this.cusPhone = cusPhone == null ? null : cusPhone.trim();
} public String getCusEmail() {
return cusEmail;
} public void setCusEmail(String cusEmail) {
this.cusEmail = cusEmail == null ? null : cusEmail.trim();
}
}

上面红色加粗的部分就是使用JSR 303中的约束规则。

3、创建校验器

这个校验器用来判断输入的用户名是不是Administrator,如果是则校验不通过,并给出提示,否则校验成功;

public class CustomerValidator implements Validator {
/**
* 检验验证对象是不是Customer类,如果是则进行检验
*/
@Override
public boolean supports(Class<?> target) {
return Customer.class.equals(target);
} /**
* 校验用户名是否已经存在
*/
@Override
public void validate(Object target, Errors errors) {
Customer customer = (Customer) target;
String name = customer.getCusName();
if (name.equals("Administrator")) {
errors.rejectValue("cusName", null, "该账号已被使用!"); }
} }

创建校验器时只要实现Validator接口并重写对应的方法即可,supports方法是用来判定要校验的bean类型,validate方法用来完成校验逻辑。

4、创建控制器

@Controller
@RequestMapping("/customer")
public class CustomerController { @Autowired
@Qualifier("customerService")
CustomerService customerServiceImpl = null; /**
* 绑定验证器
*
* @param dataBinder
*/
@InitBinder
public void bindValidator(DataBinder dataBinder) {
dataBinder.setValidator(new CustomerValidator());
} /**
* customer首页
*
* @param mv
* @param customer
* @return
*/
@RequestMapping("index")
public ModelAndView indexCustomer(ModelAndView mv, Customer customer) {
mv.addObject("customer", customer);
mv.setViewName("index");
mv.addObject("customer", customer);
return mv;
} @RequestMapping(value = "addCustomer", method = RequestMethod.POST)
public ModelAndView validByAnnotation(@Valid Customer customer, Errors errors,
RedirectAttributes redirectAttributes) {
ModelAndView mv = new ModelAndView();
// 判断是否存在错误
if (errors.hasErrors()) {
List<FieldError> errorList = errors.getFieldErrors();
for (FieldError fieldError : errorList) {
System.out.println("field:" + fieldError.getField() + ";errors:" + fieldError.getDefaultMessage());
}
mv.addObject("errorList", errorList);
mv.setView(new MappingJackson2JsonView());
} else {
boolean insert = customerServiceImpl.addCustomer(customer);
redirectAttributes.addFlashAttribute("customer", customer);
if (insert) {
mv.setViewName("redirect:./customer/index");
} else {
mv.setViewName("redirect:./customer/error");
}
}
return mv;
} /**
* 出错页面
*
* @param mv
* @param customer
* @return
*/
@RequestMapping("error")
public ModelAndView errorInfo(ModelAndView mv, Customer customer) {
mv.addObject("customer", customer);
mv.setViewName("customer/error");
return mv;
} }

这个控制器逻辑如下:

  • 首先在方法bindValidator上使用注解@InitBinder完成校验器和控制器的绑定;
  • 然后使用注解@Valid对Customer进行校验,这样校验器中就能通过第一个方法的判断;
  • 通过Error对象判断是不是有错误,如果有错误代表校验失败,失败后打印出失败的信息并返回JDON视图;
  • 如果校验成功则将数据保存在数据库,保存时也判断是否成功,保存成功则返回index页面,否则返回error页面

5、测试

先来测试JSR 303的校验,首先在页面输入以下信息,输入信息都是不通过校验的:

返回信息如下:

其实就是校验失败的提示信息,我是直接返回JSON视图的,所以说明JSR 303校验生效了。下面输入一些合法数据进行测试:

点击提交之后的结果如下:

保存成功并进入index页面,校验成功。

下面测试校验器功能,需要释放绑定逻辑,输入以下正确信息,并让用户名为Administrator

提交之后的结果如下:

从提示信息看出校验器校验没用通过并给出提示信息,说明校验通过了。

以上就是Spring MVC中对表单进行服务端校验的内容。

Spring MVC(十四)--SpringMVC验证表单的更多相关文章

  1. spring mvc Controller与jquery Form表单提交代码demo

    1.JSP表单 <% String basePath = request.getScheme() + "://" + request.getServerName() +&qu ...

  2. Spring MVC(十五)--SpringMVC国际化配置项

    Spring MVC中,当DispatcherServlet初始化的时候,会解析一个LocaleResolver接口的实现类,这个实现类就是用来解析国际化的. 一.国际化解析器 Spring MVC中 ...

  3. Spring MVC 用post方式提交表单到Controller乱码问题,而get方式提交没有乱码问题

    在web.xml中添加一个filter,即可解决post提交到Spring MVC乱码问题 <!-- 配置请求过滤器,编码格式设为UTF-8,避免中文乱码--> <filter> ...

  4. 五十四:WTForms表单验证之自定义表单验证器

    如果想要对表单中的某个字段进行自定义验证,则需要对这个字段进行单独的验证1.定义一个方法,命名规则为:validate_字段名(self, filed)2.在方法中,使用filed.data获取字段的 ...

  5. SpringMVC(十四):SpringMVC 与表单提交(post/put/delete的用法);form属性设置encrypt='mutilpart/form-data'时,如何正确配置web.xml才能以put方式提交表单

    SpringMVC 与表单提交(post/put/delete的用法) 为了迎合Restful风格,提供的接口可能会包含:put.delete提交方式.在springmvc中实现表单以put.dele ...

  6. Spring MVC 验证表单

      在实际工作中,得到数据后的第一步就是检验数据的正确性,如果存在录入上的问题,一般会通过注解校验,发现错误后返回给用户,但是对于一些逻辑上的错误,比如购买金额=购买数量×单价,这样的规则就很难使用注 ...

  7. SpringBoot非官方教程 | 第十九篇: 验证表单信息

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot19/ 本文出自方志朋的博客 这篇文篇主要简述如何 ...

  8. ASP.NET MVC异步验证是如何工作的02,异步验证表单元素的创建

    在上一篇"ASP.NET MVC异步验证是如何工作的01,jQuery的验证方式.错误信息提示.validate方法的背后"中,了解了jQuery如何验证,如何显示错误信息,本篇要 ...

  9. MVC中 jquery validate 不用submit方式验证表单或单个元素

    <script src="/Scripts/jquery-1.4.4.js"></script> <script src="/Scripts ...

随机推荐

  1. 关于a标签的href属性值的区别

    一.href="javacript:;"  这种用法不正确,这么用的话会出现浏览器访问“javascript:;”这个地址的现象: 二.href="javacript:v ...

  2. leetcood学习笔记-206-反转链表

    题目描述: 最佳解: class Solution(object): def reverseList(self, head): """ :type head: ListN ...

  3. 「题解」:07.16NOIP模拟T1:礼物

    问题 A: 礼物 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物. 商店里一共有种礼物.夏川每得到一种礼 ...

  4. POJ3436:ACM Computer Factory-最大流

    目录 目录 思路: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 目录 题意:传送门  原题目描述在最下面.  题目真难读懂 有\(n\)台机器,每台机器有\(p\)个部分,每台机 ...

  5. python list基本操作一

    a = [1,2,3,1,2,3] 一.删除元素 1.按索引删除: a.pop(1) # 删除第二个值 # in:[1,2,3,2] # out:[1,3,2] 返回值:被删除的元素,这个时候list ...

  6. jquery操作html元素之( 获取并设置 CSS 类)

    jQuery 操作 CSS jQuery 拥有若干进行 CSS 操作的方法.我们将学习下面这些: addClass() - 向被选元素添加一个或多个类 removeClass() - 从被选元素删除一 ...

  7. Python3数据分析与挖掘建模实战✍✍✍

    Python3数据分析与挖掘建模实战 Python数据分析简介 Python入门 运行:cmd下"python hello.py" 基本命令: 第三方库 安装 Windows中 p ...

  8. haproxy Mycat集2---KeepAlived

    KA 配两台 MASTER,BACKUP节点 安装Keepalived 1.下载安装依赖包 yum install -y wget make gcc openssl-devel popt-devel ...

  9. mysql 触发器实现级联删除有外键的多张表

    2019-10-12 10:17:44 1.数据,建表时有可能会报错,只需要把前三行注释删掉就行 -- ---------------------------- -- Table structure ...

  10. mysql分区partition详解

    分区管理  论坛 1. RANGE和LIST分区的管理 针对非整形字段进行RANG\LIST分区建议使用COLUMNS分区.  RANGE COLUMNS是RANGE分区的一种特殊类型,它与RANGE ...