`
Adan-Chiu
  • 浏览: 21818 次
社区版块
存档分类
最新评论

spring MVC组件开发-表单数据校验

 
阅读更多

       在实际工作中,得到数据后的第一步就是校验数据的正确性,如果存在录入上的问题,一般先经过前端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'
}

 

  • 大小: 16.8 KB
分享到:
评论

相关推荐

    Spring In Action MVC 提交表单(2)-数据绑定和数据校验

    在实际开发中,我们可能使用诸如IntelliJ IDEA或Eclipse等IDE,它们提供了对Spring MVC数据绑定和校验的强大支持,包括代码提示、错误检测和自动修复。 综上所述,Spring MVC的数据绑定和数据校验机制为开发者提供...

    最全最经典spring-mvc教程

    对于验证,Spring MVC提供了BindingResult和Validator接口,用于校验模型数据的正确性。 另外,Spring MVC与Spring框架的其他组件无缝集成,如Spring AOP(面向切面编程)用于实现日志、事务管理等功能,Spring ...

    spring mvc 4.0

    6. **数据绑定与验证**:Spring MVC提供了数据绑定和验证功能,允许将表单数据自动绑定到Java对象,并进行校验,简化了业务逻辑处理。 7. **视图解析**:Spring MVC 4.0支持多种视图技术,如JSP、FreeMarker、...

    spring、 spring mvc、 mybatis 开发的java客户关系管理系统,前端采用easyui编写.zip

    本文将深入探讨一款基于Spring、Spring MVC、MyBatis框架开发的Java CRM系统,以及其前端采用的EasyUI技术。 1. Spring框架:Spring是Java企业级应用开发的核心框架,提供了一种依赖注入(DI)和面向切面编程(AOP...

    Spring MVC 基础实例源码01

    11. **Validation**:Spring提供了数据验证机制,可以通过`@Valid`注解和Validator接口实现对表单数据的校验。 12. **Interceptor**:拦截器,允许在请求处理前后执行自定义逻辑,如日志记录、权限检查等。 13. **...

    spring MVC_快速入门

    Spring MVC支持自动的数据绑定,可以将请求参数直接绑定到Controller方法的参数上,也可以将表单数据绑定到Java对象。此外,@Valid用于验证模型数据,配合Validator接口实现自定义校验规则。 7. **异常处理** ...

    最简单的用户登录与注册系统 spring mvc spring jdbc

    这个项目是一个基于Spring MVC和Spring JDBC的简单用户管理应用,旨在帮助初学者理解如何在实际开发中实现用户登录、注册以及信息修改功能。Spring MVC是Spring框架的一个模块,主要用于构建Web应用程序,而Spring ...

    spring mvc

    7. **Form Handling**: Spring MVC 提供了强大的表单处理能力,包括自动数据绑定、数据校验等功能。通过@Valid可以进行数据验证,@RequestParam和@PathVariable用于获取请求参数。 8. **Interceptors**: 拦截器是...

    Spring MVC A Tutorial Second Edition

    验证器(Validators)是用于校验数据有效性的组件,在Spring MVC中,验证通常与JSR-303规范紧密相关。通过使用注解(如@Valid),可以对模型对象进行校验,并处理验证失败的情况。 表达式语言(Expression Language...

    spring mvc4 详细教程 PDF

    9. Spring MVC表单标签和处理静态资源,提供了表单标签库,以及处理静态资源的方式。 10. 数据转换和数据格式化及数据校验,可以通过Spring MVC的注解来实现数据的转换、格式化和校验。 11. 处理JSON,Spring MVC...

    计算机外文翻译-Spring的web-MVC-构架模式.docx

    综上所述,Spring的Web MVC构架模式以其高度的灵活性、可扩展性和组件化的特性,成为现代Web开发中广泛采用的框架,既可作为独立的Web解决方案,也可与其他技术无缝集成,以满足各种复杂应用的需求。

    计算机外文翻译-Spring的web-MVC-构架模式.pdf

    - Spring MVC中的模型通常由命令对象、表单对象以及任意的参考数据组成,这与WebWork的Action对象有所不同。WebWork将控制器、命令对象和表单数据合并到一个对象中。 - 视图解析是Spring MVC中的另一个关键部分,...

    springmvc01.zip_DEMO_JSON校验_spring mvc

    本DEMO是针对Spring MVC的学习实践,主要涵盖了JSON数据校验、文件上传以及返回JSON数据的配置,对初学者来说非常有帮助。 **1. JSON校验** 在Spring MVC中,我们可以使用JSR-303/JSR-349标准的Bean Validation框架...

    spring mvc服务端表单验证实例

    在Spring MVC框架中,服务端表单验证是一个关键的步骤,确保从客户端接收到的数据是有效和安全的。本实例提供了完整的代码和配置,让你能够快速理解和应用服务端验证。以下是对这个实例的详细解析: 1. **Spring ...

    spring mvc校验

    在Spring MVC框架中,数据校验是一个至关重要的环节,它确保了输入的数据符合业务规则,降低了因错误数据引发的问题。这篇博文"spring mvc校验"可能深入探讨了如何在Spring MVC项目中实现有效的数据验证。 首先,...

    Spring-MVC --- Complete-Concepts-Beginner-:项目中完整的MVC初学者概念

    Spring MVC 支持表单数据的绑定和验证。我们可以使用 @ModelAttribute 注解将表单数据绑定到模型对象,使用 Hibernate Validator 或自定义验证规则进行数据校验。 9. **RESTful Web Services** Spring MVC 也支持...

    外文翻译-Spring的web-MVC-构架模式讲解学习.pdf

    - **Struts**:与Struts相比,Spring MVC更强调控制器的独立性,不需要ActionForm基类,可以不依赖Web表单,提供更灵活的数据绑定和校验机制。 - **WebWork(现在称为Struts2)**:Spring MVC与WebWork的主要区别...

    spring mvc入门小例子

    6. **Form Handling**:Spring MVC提供了强大的表单处理能力,包括数据绑定和验证。`@RequestParam`用于从请求参数中获取数据,`@Valid`用于进行数据校验。 7. **Interceptor**:拦截器允许我们在请求处理前后执行...

Global site tag (gtag.js) - Google Analytics