最早的校验,就是服务端校验。早期的网站,用户输入一个邮箱地址,校验邮箱地址需要将地址发送到服务端,服务端进行校验,校验成功后,给前端一个响应。有了JavaScript,校验工作可以放在前端去执行。那么为什么还需要服务端校验呢? 因为前端传来的数据不可信。前端很容易获取都后端的数据接口,如果有人绕过页面,就会出现非法数据,所以服务端也要数据校验,总的来说:
1.前端校验要做,目的是为了提高用户体验
2.后端校验也要做,目的是为了数据安全
springmvc中并没有提供校验的功能,它使用hibernate-validator进行数据校验
1.导入相关jar包
2.创建validateMessage.properties文件,用于声明错误提示信息
将properties文件的属性中的Resource中的encoding改为utf-8可显示中文
user.username.empty=账号不能为空
user.username.size=账号长度为3-6位
user.password.size=密码长度为3-6位
3.配置springmvc中的配置文件
<context:component-scan base-package="com.springmvc.controller">context:component-scan>
<mvc:annotation-driven validator="validator">mvc:annotation-driven>
<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:validateMessage"/>
<property name="defaultEncoding" value="utf-8"/>
<property name="cacheSeconds" value="120"/>
bean>
4.在Bean对象中配置校验规则
public class User {
@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;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
校验规则注解说明
注解 | 说明 |
---|---|
@Null | 被注解的元素必须为空 |
@NotNull | 被注解的元素必须不为空 |
@AssertTrue | 被注解的元素必须为true |
@AssertFlase | 被注解的元素必须为false |
@Min(value) | 被注解的元素必须是数字,且必须大于指定的最小值 |
@Max(value) | 被注解的元素必须是数字,且必须小于指定的最大值 |
@DecimalMin(value) | 被注解的元素必须是数字,且必须大于指定的最小值 |
@DecaimalMax(value) | 被注解的元素必须是数字,且必须小于指定的最大值 |
@Size(max=,min=) | 被注解元素的大小必须在指定的范围内 |
@Digit(integer,fraction) | 被注解元素必须是数字,且其值必须在可接受的范围内 |
@Past | 被注解元素必须是一个过去的日期 |
@Futrue | 被注解元素必须是一个将来的日期 |
@Pattern(regex=,flag=) | 被注解元素必须符合指定的正则表达式 |
@NotBlank | 验证非空,且长度必须大于0 |
被注解的元素必须是电子邮件地址 | |
@Length(max=,min=) | 被注解的字符串大小必须在指定的范围内 |
@NotEmpty | 被注解的字符串必须非空 |
@Range(max=,min=) | 被注解的元素必须在指定范围内 |
5.在Controller中校验
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/add")
public String add(@Validated User user,BindingResult br,Model m) {
System.out.println(user);
List<ObjectError> allErrors = br.getAllErrors();
for (ObjectError objectError : allErrors) {
System.out.println(objectError.getDefaultMessage());
}
m.addAttribute("errors", allErrors);
return "/index.jsp";
}
}
6.jsp接收校验结果
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>HelloWorldtitle>
head>
<body>
Hello World
<c:if test="${errors ne null}">
<c:forEach items="${errors}" var="e">
${e.defaultMessage}<br>
c:forEach>
c:if>
body>
html>
为什么需要分组校验?
因为一个对象有多个属性,而不同的controller校验的需求是不一样的,必须c1只需要校验对象的账号是否为空就可以了,而c2不光要校验账号为空还需要校验手机号必须不能为空,这时分组校验就能解决这个问题了。实现步骤如下:
1.定义分组
package com.springmvc.group;
public interface Group1 {
}
2.使用分组
@NotBlank(message="{user.username.empty}",groups=Group2.class)
@Size(max=6,min=3,message="{user.username.size}",groups=Group1.class)
private String username;
@Size(max=6,min=3,message="{user.password.size}",groups=Group1.class)
private String password;
3.在Controller中使用
@RequestMapping("/add")
public String add(@Validated(value=Group1.class) User user,BindingResult br,Model m) {
System.out.println(user);
List<ObjectError> allErrors = br.getAllErrors();
for (ObjectError objectError : allErrors) {
System.out.println(objectError.getDefaultMessage());
}
m.addAttribute("errors", allErrors);
return "/index.jsp";
}