在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. apache httpd.conf alias

    参考 Apache alias目录配置 我的环境是 Ubuntu apache2,配置文件目录在 /etc/apache2/sites-available/000-default.conf 在这个配置 ...

  2. fastJson中常用方法以及遇到的“坑”

    1.使用fastJson,首先引入fastJson依赖 <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> & ...

  3. 编译Solr4.72 源码没有成功

    最近需要用到solr,查询Hbase里面的数据,编译Solr的时候遇到了点问题: 下了solr的源码后需要用ant自己编译: 源码下载地址:https://svn.apache.org/repos/a ...

  4. codeforces round#524 C. Masha and two friends /// 矩形切割

    题目大意: 给定n行m列的黑白棋盘如下 给定矩形的左下点x1 y1和右上点x2 y2将这个区域都涂成白色 再给定矩形的左下点x3 y3和右上点x4 y4将这个区域都涂成黑色 求最后棋盘内有分别多少个白 ...

  5. Number Sequence /// oj21456

    题目大意: 有一组规律数 the first 80 digits of the sequence are as follows: 1 12 123 1234 12345 123456 1234567 ...

  6. libevent的使用 32位 64位

    前段时间一个项目需要用到高并发的服务,想着自己应该可以写一个,windwos 上使用完成端口实现,写完之后,测试感觉没什么问题,可是一上线各种各样的问题,初步怀疑是底层网路库的问题,于是决定更换网络库 ...

  7. 国行iphone第一次安装APP网络状况

    国行手机第一次安装APP,会有请求网络权限的一个弹框出现,在这期间APP是没有任何网络连接的. 想必大部分APP的需求和这个逻辑有冲突. 先推荐一个链接:http://www.cocoachina.c ...

  8. python、Jupyter运行时间

    1.Python time time()方法 import time time_start=time.time() time_end=time.time() print('totally cost', ...

  9. Linux 常用命令:解压缩篇

    前言 Linux常用命令中,有很多用于对文件的压缩或解压,本文将介绍这些解压缩命令中不常见却非常实用的用法. tar tar是linux中最常用的解压缩命令.tar命令可用于处理后缀名为tar,tar ...

  10. ipsec原理(转载)

    IPSec VPN是目前VPN技术中点击率非常高的一种技术,同时提供VPN和信息加密两项技术,这一期专栏就来介绍一下IPSec VPN的原理.IPSec VPN应用场景 IPSec VPN的应用场景分 ...