在实际工作中,得到数据后的第一步就是校验数据的正确性,如果存在录入上的问题,一般先经过前端js进行验证,但是前端有多种方式可以绕过前端js验证(不是安全有效的),为了数据安全性一般还需要在服务器端做数据校验。这个时候就可以使用spring所提供的验证器(Validator)规则去验证。
所有的验证都是要先注册验证器,不过验证器也是springmvc自动加载的。我们 使用hibernate校验规则。
使用JSR 303注解验证输入内容
Spring 提供了对Bean的功能校验,通过注解@Valid标明哪个Bean需要启用注解式的验证。在javax.validation.constrains.*中定义了一系列的JSR 303规范给出的注解:
限制
|
说明
|
@Null
|
限制只能为null
|
@NotNull
|
限制必须不为null
|
@AssertFalse
|
限制必须为false
|
@AssertTrue
|
限制必须为true
|
@DecimalMax(value)
|
限制必须为一个不大于指定值的数字
|
@DecimalMin(value)
|
限制必须为一个不小于指定值的数字
|
@Digits(integer,fraction)
|
限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
|
@Future
|
限制必须是一个将来的日期
|
@Max(value)
|
限制必须为一个不大于指定值的数字
|
@Min(value)
|
限制必须为一个不小于指定值的数字
|
@Past
|
限制必须是一个过去的日期
|
@Pattern(value)
|
限制必须符合指定的正则表达式
|
@Size(max,min)
|
限制字符长度必须在min到max之间
|
@Email
|
邮箱类型
|
@NotEmpty
|
集合,不为空
|
@NotBlank
|
不为空字符串
|
@Positive
|
数字,正数
|
@PositiveOrZero
|
数字,正数或0
|
@Negative
|
数字,负数
|
@NegativeOrZero
|
数字,负数或0
|
@PastOrPresent
|
过去或者现在日期
|
@FutrueOrPresent
|
将来或者现在日期
|
为了使用这些注解,假设要完成一个保存雇员表单:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>添加员工</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/control/emp/save" method="post" >
用户名:<input type="text" name="username" placeholder="请输入用户名,最小4位,最大12位" required/>
<span></span>
<br/>
密码:<input type="password" name="password" placeholder="请输入登录密码"/><br/>
电子邮箱:<input type="email" name="email" placeholder="请输入电子邮箱"/><br/>
员工生日:<input type="date" name="bornDate" /><br/>
薪水:<input type="number" name="salary" placeholder="请输入员工薪水" /><br/>
联系电话:<input type="text" name="phone" placeholder="请输入员工联系电话" pattern="^1[358]\d{9}$"/><br/>
员工简介:
<textarea placeholder="请输入员工简介" name="intro"></textarea>
<br/>
<input type="submit" value="提交" /> <input type="reset">
</form:form>
</body>
</html>
校验规则:
- 户名,密码,电子邮箱,入职日期不能为空
- 入职日期格式为yyyy-MM-dd,且只能大于今日
- 生日日期格式为yyyy-MM-dd,且只能是一个过去日期
- 邮箱需要符合格式:
- 简介内容不得多于256个字符
- 薪水最小值为2000,最大值为5万
- 联系方式需为正确的手机号码(使用正则表达式匹配)
建立pojo,确定校验规则:
public class Employee {
private Integer id;
/**
* 用户名,不允许为空,最小4位,最大12位
*/
@NotBlank(message = "用户名不能为空")
@Size(min = 4,max = 12,message = "{employee.username.valid.size.message}")
private String username;
/**
* 密码:不能为空,最小6位
*/
@NotBlank(message = "密码不能为空")
@Size(min = 6,max = 12,message = "密码最低6位")
private String password;
/**
* 电子邮箱,不能为空,要满足邮箱基本格式
*/
@NotNull(message = "邮箱不能为空")
@Email(message="邮箱必须满足基本格式")
private String email;
/**
* 员工生日,格式为:yyyy-MM-dd
* 必须是一个过去的日期
*/
@DateTimeFormat(iso = ISO.DATE)
@Past(message = "你不能录用还未出生的员工")
private LocalDate bornDate;
/**
* 入职日期,格式为:yyyy-MM-dd
* 必须是一个现在或者将来的日期
*/
@DateTimeFormat(iso = ISO.DATE)
@FutureOrPresent
private LocalDate entryDate = LocalDate.now();
/**
* 员工联系(手机)电话
* 必须符合手机号码格式(正则表达式)
*/
@Pattern(regexp = "^1[358]\\d{9}$",message = "请输入正确的手机号码")
private String phone;
/**
* 员工薪水,最低2000,最高5万
*/
@Min(value = 2000,message="工资不能低于2000,否则麻烦了")
@Max(value=50000,message="工资不能大于50000,否则交奢侈税")
private float salary;
/**
* 员工简介,最大不超过200
*/
@Size(min = 6,max = 12,message = "员工简介不能超过200字")
private String intro;
//***************setter and getter*************/
}
这样就定义了一个pojo,用于接收表单的信息。字段上面的注解反映了对每一个字段的验证要求,这样就可以加入对应校验,如果没有指定message属性,会生成默认的错误信息。message配置项用来定义当校验失败后的错误信息,这样就能启动Spring的检验规则来校验表单了。
用控制器验证表单:
@Controller
@RequestMapping("/control/emp")
public class EmployeeController {
@RequestMapping("/save")
public String save(@Valid Employee emp,BindingResult errors) {
if(errors.hasErrors()) {
return "emp/emp_save";
}
return "redirect:./list";
}
}
使用了注解@Valid标明这个Bean将会被校验,另外一个类型为
BindingResult的参数(或者为Errors)是用于保存校验是否存在错误信息的,也就是当采用JSR 303规范进行校验后,它会将这个错误信息保存到这个参数中,在方法中判断是否有错误信息,如果有错误信息,跳转到填写表单页面告诉用户错误信息。
如何在jsp页面中显示错误信息呢?这时可以使用jsp提供给我们的标签库
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html>
<html>
<head>
<title>添加员工</title>
</head>
<body>
<form:form action="${pageContext.request.contextPath }/control/emp/save" method="post" modelAttribute="employee">
用户名:<input type="text" name="username" placeholder="请输入用户名,最小4位,最大12位" required/>
<span><form:errors path="username" cssStyle="color: red"/></span>
<br/>
密码:<input type="password" name="password" placeholder="请输入登录密码"/><br/>
电子邮箱:<input type="email" name="email" placeholder="请输入电子邮箱"/><br/>
员工生日:<input type="date" name="bornDate" /><br/>
薪水:<input type="number" name="salary" placeholder="请输入员工薪水" /><br/>
联系电话:<input type="text" name="phone" placeholder="请输入员工联系电话" pattern="^1[358]\d{9}$"/><br/>
员工简介:
<textarea placeholder="请输入员工简介" name="intro"></textarea>
<br/>
<input type="submit" value="提交" /> <input type="reset">
</form:form>
</body>
</html>
看起来似乎非常不错,但是我们的message错误提示信息是硬编码在pojo身上,为了避免其硬编码而实现可配置,我们在src/main/resource下新建messageSource.properties文件:
employee.username.valid.notnull.message=用户名不能为空
employee.username.valid.size.message=用户名不能少于4位且不能超过12位
上面简单罗列了两个错误信息配置,其它道理一样,哪怎么应用(读取)指定的错误信息呢?在pojo验证规则之上:
/**
* 用户名,不允许为空,最小4位,最大12位
*/
@NotBlank(message = "{employee.username.valid.notnull.message}")
@Size(min = 4,max = 12,message = "{employee.username.valid.size.message}")
private String username;
可以采用{}表达式对配置文件的key加以读取其对应的value。其它字段同理,到这里还不能读取指定配置文件,需要告诉spring的检验器加载什么样的配置文件,配置代码如下:
@Configuration
@ComponentScan(basePackages = "com.wise.tiger.web")
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer{
@Bean
public InternalResourceViewResolver viewResolver() {
var viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/pages/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Override //静态资源不被前端控制器拦截
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")//添加静态资源的url-pattern
.addResourceLocations("/static/");
}
@Bean
public ReloadableResourceBundleMessageSource messageResource() {
var messageResource = new ReloadableResourceBundleMessageSource();
//如果不指定,默认会去classpath下的messages.properties配置文件
messageResource.setBasename("classpath:resourceMessage");
return messageResource;
}
/**
* 添加表单校验器
*/
@Override
public Validator getValidator() {
var validator = new LocalValidatorFactoryBean();
validator.setProviderClass(HibernateValidator.class);
validator.setValidationMessageSource(messageResource());
return validator;
}
}
分组校验
1.定义分组:可以采用标识接口来进行分组区分
//分组校验1
public interface ValidationGroup1 {
}
//分组校验2
public interface ValidationGroup2 {
}
2.在检验规则上添加分组
/**
* 用户名,不允许为空,最小4位,最大12位
*/
@NotBlank(message = "{employee.username.valid.notnull.message}",groups = ValidationGroup1.class)
@Size(min = 4,max = 12,message = "{employee.username.valid.size.message}",groups = ValidationGroup2.class)
private String username;
3.在conroller中指定使用的分组校验
@Controller
@RequestMapping("/control/emp")
public class EmployeeController {
@RequestMapping("/save")
public String save( @Validated(ValidationGroup2.class) @ModelAttribute Employee emp,BindingResult errors,Model model) {
if(errors.hasErrors()) {
for (var i = 0; i < errors.getErrorCount();i++) {
System.out.println(errors.getObjectName() + ":" + errors.getFieldError().getDefaultMessage());
}
return "emp/emp_save";
}
return "redirect:./list";
}
}
有时候除了简单的输入格式、非空性等校验,也需要一定的业务校验,Spring提供了Validator接口来实现校验,它将在进入控制器逻辑之前对参数的合法性进行校验。核心代码如下:
public interface Validator {
/**
* 判断当前校验器是否用于检验clazz类型的pojo
* @param clazz -- pojo类型
* @return true 启动校验,false 不校验
*/
@Override
public boolean supports(Class<?> clazz) {
return false;
}
/**
* 检验pojo的合法性
* @param target 请求对象
* @param errors 错误信息
*/
@Override
public void validate(Object target, Errors errors) {
}
}
Validator接口是SpringMvc校验表单的核心接口,它只是一个验证器,在Spring中最终被注册到验证器的列表中,这样就可以提供给各个控制器去定义,然后通过supports方法判定是否会启用验证器去验证数据。对于校验的过程,则是通过validate方法去实现的。
package com.wise.tiger.pojo;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
/**
* @Description: 员工校验器
* @author: <a href="mailto:1020zhaodan@163.com">Adan</a>
* @date: 2019年5月28日 下午7:23:40
* @version:1.0-snapshot
*/
public class EmployeeValidator implements Validator {
/**
* 判断当前校验器是否用于检验clazz类型的pojo
* @param clazz -- pojo类型
* @return true 启动校验,false 不校验
*/
@Override
public boolean supports(Class<?> clazz) {
//判断验证是否为Employee,如果是则进行校验
return Employee.class.equals(clazz);
}
/**
* 检验pojo的合法性
* @param target 请求对象
* @param errors 错误信息
*/
@Override
public void validate(Object target, Errors errors) {
var employee = (Employee)target;
//对employee pojo类中年薪计算规则为薪水 * 16
var yearlySalary = employee.getSalary() * 16;
//如果年薪小于1,则认为业务错误
if(yearlySalary < 1)
//加入错误信息
errors.rejectValue("yearlySalary", null, "年薪和月薪不匹配,月薪输入错误");
}
}
需要将该验证器捆绑到对应的控制器中,Spring MVC提供了注解@InitBinder,通过该注解就可以将验证器和控制器捆绑在一起,这样就能对请求表单进行验证了。
@Controller
@RequestMapping("/control/emp")
public class EmployeeController {
@InitBinder
public void initBinder(DataBinder binder){
//数据绑定器加入验证器
binder.setValidator(new EmployeeValidator());
}
@RequestMapping("/save")
public String save( @Validated(ValidationGroup2.class) @ModelAttribute Employee emp,BindingResult errors,Model model) {
if(errors.hasErrors()) {
for (var i = 0; i < errors.getErrorCount();i++) {
System.out.println(errors.getObjectName() + ":" + errors.getFieldError().getDefaultMessage());
}
return "emp/emp_save";
}
return "redirect:./list";
}
}
这样就能对比较复杂的逻辑关系进行校验了。@InitBinder的使用还有其它内容,后续讲解。。。。。。
附:依赖列表
dependencies {
compile group: 'org.springframework', name: 'spring-context', version: '5.1.7.RELEASE'
compile group: 'org.springframework', name: 'spring-webmvc', version: '5.1.7.RELEASE'
compile group: 'org.springframework', name: 'spring-test', version: '5.1.7.RELEASE'
providedCompile group: 'javax.servlet.jsp', name: 'javax.servlet.jsp-api', version: '2.3.3'
providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
compile group: 'taglibs', name: 'standard', version: '1.1.2'
compile group: 'javax.servlet', name: 'jstl', version: '1.2'
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
compile group: 'org.mybatis', name: 'mybatis-spring', version: '2.0.1'
compile group: 'org.mybatis', name: 'mybatis', version: '3.5.1'
compile group: 'com.alibaba', name: 'druid', version: '1.1.16'
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.16'
compile group: 'org.springframework', name: 'spring-jdbc', version: '5.1.7.RELEASE'
compile group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
compile group: 'org.hibernate', name: 'hibernate-validator', version: '6.0.16.Final'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.9'
}
相关推荐
在实际开发中,我们可能使用诸如IntelliJ IDEA或Eclipse等IDE,它们提供了对Spring MVC数据绑定和校验的强大支持,包括代码提示、错误检测和自动修复。 综上所述,Spring MVC的数据绑定和数据校验机制为开发者提供...
对于验证,Spring MVC提供了BindingResult和Validator接口,用于校验模型数据的正确性。 另外,Spring MVC与Spring框架的其他组件无缝集成,如Spring AOP(面向切面编程)用于实现日志、事务管理等功能,Spring ...
6. **数据绑定与验证**:Spring MVC提供了数据绑定和验证功能,允许将表单数据自动绑定到Java对象,并进行校验,简化了业务逻辑处理。 7. **视图解析**:Spring MVC 4.0支持多种视图技术,如JSP、FreeMarker、...
本文将深入探讨一款基于Spring、Spring MVC、MyBatis框架开发的Java CRM系统,以及其前端采用的EasyUI技术。 1. Spring框架:Spring是Java企业级应用开发的核心框架,提供了一种依赖注入(DI)和面向切面编程(AOP...
11. **Validation**:Spring提供了数据验证机制,可以通过`@Valid`注解和Validator接口实现对表单数据的校验。 12. **Interceptor**:拦截器,允许在请求处理前后执行自定义逻辑,如日志记录、权限检查等。 13. **...
Spring MVC支持自动的数据绑定,可以将请求参数直接绑定到Controller方法的参数上,也可以将表单数据绑定到Java对象。此外,@Valid用于验证模型数据,配合Validator接口实现自定义校验规则。 7. **异常处理** ...
这个项目是一个基于Spring MVC和Spring JDBC的简单用户管理应用,旨在帮助初学者理解如何在实际开发中实现用户登录、注册以及信息修改功能。Spring MVC是Spring框架的一个模块,主要用于构建Web应用程序,而Spring ...
7. **Form Handling**: Spring MVC 提供了强大的表单处理能力,包括自动数据绑定、数据校验等功能。通过@Valid可以进行数据验证,@RequestParam和@PathVariable用于获取请求参数。 8. **Interceptors**: 拦截器是...
验证器(Validators)是用于校验数据有效性的组件,在Spring MVC中,验证通常与JSR-303规范紧密相关。通过使用注解(如@Valid),可以对模型对象进行校验,并处理验证失败的情况。 表达式语言(Expression Language...
9. Spring MVC表单标签和处理静态资源,提供了表单标签库,以及处理静态资源的方式。 10. 数据转换和数据格式化及数据校验,可以通过Spring MVC的注解来实现数据的转换、格式化和校验。 11. 处理JSON,Spring MVC...
综上所述,Spring的Web MVC构架模式以其高度的灵活性、可扩展性和组件化的特性,成为现代Web开发中广泛采用的框架,既可作为独立的Web解决方案,也可与其他技术无缝集成,以满足各种复杂应用的需求。
- Spring MVC中的模型通常由命令对象、表单对象以及任意的参考数据组成,这与WebWork的Action对象有所不同。WebWork将控制器、命令对象和表单数据合并到一个对象中。 - 视图解析是Spring MVC中的另一个关键部分,...
本DEMO是针对Spring MVC的学习实践,主要涵盖了JSON数据校验、文件上传以及返回JSON数据的配置,对初学者来说非常有帮助。 **1. JSON校验** 在Spring MVC中,我们可以使用JSR-303/JSR-349标准的Bean Validation框架...
在Spring MVC框架中,服务端表单验证是一个关键的步骤,确保从客户端接收到的数据是有效和安全的。本实例提供了完整的代码和配置,让你能够快速理解和应用服务端验证。以下是对这个实例的详细解析: 1. **Spring ...
在Spring MVC框架中,数据校验是一个至关重要的环节,它确保了输入的数据符合业务规则,降低了因错误数据引发的问题。这篇博文"spring mvc校验"可能深入探讨了如何在Spring MVC项目中实现有效的数据验证。 首先,...
Spring MVC 支持表单数据的绑定和验证。我们可以使用 @ModelAttribute 注解将表单数据绑定到模型对象,使用 Hibernate Validator 或自定义验证规则进行数据校验。 9. **RESTful Web Services** Spring MVC 也支持...
- **Struts**:与Struts相比,Spring MVC更强调控制器的独立性,不需要ActionForm基类,可以不依赖Web表单,提供更灵活的数据绑定和校验机制。 - **WebWork(现在称为Struts2)**:Spring MVC与WebWork的主要区别...
6. **Form Handling**:Spring MVC提供了强大的表单处理能力,包括数据绑定和验证。`@RequestParam`用于从请求参数中获取数据,`@Valid`用于进行数据校验。 7. **Interceptor**:拦截器允许我们在请求处理前后执行...