最早的校验,就是服务端校验。早期的网站,用户输入一个邮箱地址,校验邮箱地址需要将地址发送到服务端,服务端进行校验,校验成功后,给前端一个响应。有了JavaScript,校验工作可以放在前端去执行。那么为什么还需要服务端校验呢? 因为前端传来的数据不可信。前端很容易获取都后端的数据接口,如果有人绕过页面,就会出现非法数据,所以服务端也要数据校验,总的来说:
1.前端校验要做,目的是为了提高用户体验
2.后端校验也要做,目的是为了数据安全
Springmvc本身没有校验功能,它使用hibernate的校验框架,hibernate的校验框架和orm没有关系
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-validatorartifactId>
<version>5.3.0.Alpha1version>
dependency>
属性文件用来声明错误提示信息
如果属性文件乱码的解决办法:
在Eclipse主界面下,打开Window->Perferences->General->ContentTypes:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<mvc:annotation-driven validator="validator">mvc:annotation-driven>
<context:component-scan base-package="com.dpb.controller">context:component-scan>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<property name="validationMessageSource" ref="validatemessageSource"/>
bean>
<bean id="validatemessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:ValidateMessages"/>
<property name="fileEncodings" value="utf-8"/>
<property name="cacheSeconds" value="120"/>
bean>
beans>
@NotBlank(message="{user.username.empty}")
@Size(max=6,min=3,message="{user.username.size}")
private String username;
@Size(max=6,min=3,message="{user.password.size}")
private String password;
校验规则
注解 | 说明 |
---|---|
@Null | 被注解的元素必须为 null |
@NotNull | 被注解的元素必须不为 null |
@AssertTrue | 被注解的元素必须为 true |
@AssertFalse | 被注解的元素必须为 false |
@Min(value) | 被注解的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Max(value) | 被注解的元素必须是一个数字,其值必须小于等于指定的最大值 |
@DecimalMin(value) | 被注解的元素必须是一个数字,其值必须大于等于指定的最小值 |
@DecimalMax(value) | 被注解的元素必须是一个数字,其值必须小于等于指定的最大值 |
@Size(max=, min=) | 被注解的元素的大小必须在指定的范围内 |
@Digits (integer, fraction) | 被注解的元素必须是一个数字,其值必须在可接受的范围内 |
@Past | 被注解的元素必须是一个过去的日期 |
@Future | 被注解的元素必须是一个将来的日期 |
@Pattern(regex=,flag=) | 被注解的元素必须符合指定的正则表达式 |
@NotBlank(message =) | 验证字符串非null,且长度必须大于0 |
被注解的元素必须是电子邮箱地址 | |
@Length(min=,max=) | 被注解的字符串的大小必须在指定的范围内 |
@NotEmpty | 被注解的字符串的必须非空 |
@Range(min=,max=,message=) | 被注解的元素必须在合适的范围内 |
/**
* 数据校验案例
*
* @author dpb【波波烤鸭】
*
*/
@Controller
public class UserController {
/**
* @Validated book 表示book接收的数据需要根据指定的规则进行校验
* BindingResult 封装验证结果,必须紧跟在验证变量之后,
* 如果有多个信息需要验证那么就有多个BindingResult参数
*
*/
@RequestMapping("/add")
public String add(@Validated Book book,BindingResult br,Model m){
System.out.println(book);
// 获取验证信息
List<ObjectError> allErrors = br.getAllErrors();
for (ObjectError objectError : allErrors) {
System.out.println(objectError.getDefaultMessage());
}
// 将验证信息保存到作用域中
m.addAttribute("errors", allErrors);
return "/index.jsp";
}
}
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
hello world<br/>
<c:if test="${errors ne null }">
<c:forEach items="${errors}" var="e">
${e.defaultMessage}<br>
c:forEach>
c:if>
body>
html>
为什么需要分组校验?
因为一个对象有多个属性,而不同的controller校验的需求是不一样的,必须c1只需要校验对象的账号是否为空就可以了,而c2不光要校验账号为空还需要校验手机号必须不能为空,这时分组校验就能解决这个问题了。实现步骤如下:
package com.dpb.group;
/**
* 定义的两个接口什么都没定义为标志接口
* @author dpb【波波烤鸭】
*
*/
public interface GroupInferface1 {
}
@NotBlank(message="{user.username.empty}"
,groups={GroupInferface2.class})
@Size(max=6,min=3,message="{user.username.size}"
,groups={GroupInferface1.class})
private String username;
@Size(max=6,min=3,message="{user.password.size}"
,groups={GroupInferface1.class})
private String password;
/**
* @Validated book 表示book接收的数据需要根据指定的规则进行校验
* BindingResult 封装验证结果,必须紧跟在验证变量之后,
* 如果有多个信息需要验证那么就有多个BindingResult参数
*
*/
@RequestMapping("/add1")
public String add1(@Validated(value=GroupInferface1.class) Book book,BindingResult br,Model m){
System.out.println(book);
// 获取验证信息
List<ObjectError> allErrors = br.getAllErrors();
for (ObjectError objectError : allErrors) {
System.out.println(objectError.getDefaultMessage());
}
// 将验证信息保存到作用域中
m.addAttribute("errors", allErrors);
return "/index.jsp";
}