一、 JSR 303是java为bean数据合法性校验提供的标准框架,它已经包含在javaee6.0中。JSR 303通过在Bean属性上标注类似于@NotNull、@Max等标准的注解指定校验规则,并通过这些标准的验证接口对Bean进行验证。
JSR 303 基本的校验规则
注解 作用
@Valid 被注释的元素是一个对象,需要检查此对象的所有字段值
@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(value) 被注释的元素必须符合指定的正则表达式
二、Hibernate Validator是JSR 303的一个参考实现,除支持所有的标准校验注解外,她还支持一下的扩展注解。
注解 作用
@Email 被注释的元素必须是电子邮箱地址
@Length(min=, max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=, max=) 被注释的元素必须在合适的范围内
@NotBlank 被注释的字符串的必须非空
@URL(protocol=,host=, port=,regexp=, flags=) 被注释的字符串必须是一个有效的url
@CreditCardNumber 被注释的字符串必须通过Luhn校验算法,银行卡,信用卡等号码一般都用Luhn计算合法性
@ScriptAssert(lang=, script=, alias=) 要有Java Scripting API 即JSR 223("Scripting for the JavaTM Platform")的实现
@SafeHtml(whitelistType=,additionalTags=) classpath中要有jsoup包
三、Spring拥有自己独立的数据校验框架,同时支持JSR 303标准的校验框架。
Spring在进行数据绑定时,可通过调用校验框架完成数据校验工作。在SpringMVC中,可直接通过注解驱动的方式进行数据校验。
Spring的LocalValidatorFactoryBean既实现了Spring的Validator接口,也实现了JSR 303的Validator接口。只要在Spring容器中定义了一个LocalValidatorFactoryBean,即可将注入到需要的数据校验的Bean中。
Spring本身并没有提供JSR 303的实现,所以必须将JSR 303的实现者jar包放在类路径下。
在maven配置文件中加入Hibernate Validator的依赖包。
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
四、<mvc:annotation-driven></mvc:annotation-driven>
会默认装配好一个LocalValidatorFactoryBean,通过在处理方法的入参上标注@Validated注解即可让Spring MVC在完成数据绑定后执行数据校验的工作。
所以需要在spring mvc配置文件中加入以下代码:
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<mvc:annotation-driven validator="validator"></mvc:annotation-driven>
五、在bean的属性上添加对应的注解。
package com.xintoucloud.ssh.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
@Entity@Table(name="t_user")
public class User {
@Id@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@NotEmpty(message="用户名必须填写")
@Size(min=4,message="不少于四个字符")
private String username;
@NotEmpty(message="密码不能为空")
@Size(min=4,max=12,message="密码长度4-15个字符")
private String userpwd;
@Email(message="邮箱格式不正确")
private String email;
private String address;
private String hobby;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpwd() {
return userpwd;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
}
六、控制器上我做了一个用户注册的例子,@Validated+BindingResult进行controller参数校验,Model将验证信息的提示信息传到视图层
BindingResult result,可以
package com.xintoucloud.ssh.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.Validator;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.xintoucloud.ssh.entity.User;
import com.xintoucloud.ssh.service.UserService;
import com.xintoucloud.ssh.service.impl.UserServiceImpl;
@Controller@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/register")
public String toregister() {
return "register";
}
@PostMapping("/register")
public String register(@Validated User user,BindingResult result,Model m) {
Map<String,String> errormessage=new HashMap<>();
if(result.hasErrors()) {
List <ObjectError> objecterrors=result.getAllErrors();
for (ObjectError objectError : objecterrors) {
if(objectError instanceof FieldError) {
FieldError fe=(FieldError)objectError;
String filename=fe.getField();
String message=fe.getDefaultMessage();
errormessage.put(filename, message);
m.addAttribute("errorsmsg", errormessage);
}
}
return "register";
}
userService.saveUser(user);
return "login";
}
}
八、注册页面上用jstl加上控制器传过来的错误信息显示出来,这里要加上jstl的依赖,还要做jsp的视图解析
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
在spring mvc的配置文件中加入jsp的视图解析
<!--支持jsp视图解析 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
register.jsp使用jstl将model传过来的验证提示(errorsmsg)信息展示
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:forEach items="${errorsmsg }" var="es">
${es.key }:${es.value }<br/>
</c:forEach>
<form method="post" action="register">
用户名:<input name="username"/><br/>
密 码:<input type="password" name="userpwd"/><br/>
邮 箱:<input name="email"><br/>
地 址:<input name="address"><br/>
爱 好:<input type="checkbox" name="hobby" value="唱歌">唱歌
<input type="checkbox" name="hobby" value="跳舞">跳舞<br/>
<input type="submit" value="提交">
</form>
</body>
</html>
九、测试:我安装的jetty内置服务器测试
我用注解设置的用户名密码不能为空,并且用户名是不少于四位,密码介于四到十五位,邮箱符合电子邮箱格式。
我们来测试一下:
1.什么都不输入情况下,直接点提交
2.用户名密码输入的位数不符合规定:
输入两位,点提交
结果是:
3。用户名,密码合法,邮箱不合法
结果是:
4.全都合法:
注册成功,跳转到登录界面
数据库中也已经存储了: