Spring MVC数据校验
数据校验是每个项目中必不可少的模块,SpringMVC提供了两种数据校验的组件:
- 基于Validator接口进行校验
- 使用Annotation JSR-303标准校验
使用基于Validator接口进行校验会复杂一些,因为具体的数据校验规则需要开发者手动设置,而使用Annotation JSR-303标准相对简单一些,开发者不需要编写校验规则,直接通过注解的形式给每一条数据添加验证规则,具体的操作是直接在实体类的属性上添加对应的校验注解即可。
基于Validator接口
1、创建实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.bitzh.entity;
import lombok.Data;
@Data public class Student { private String name; private String password; }
|
2、自定义数据校验器StudentValidation,实现Validator接口,并且需要重写接口的抽象方法,加入校验的规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.bitzh.validation;
import com.bitzh.entity.Student; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator;
public class StudentValidation implements Validator { @Override public boolean supports(Class<?> clazz) { return Student.class.equals(clazz); }
@Override public void validate(Object target, Errors errors) { ValidationUtils.rejectIfEmpty(errors,"name",null,"姓名不能为空"); ValidationUtils.rejectIfEmpty(errors,"password",null,"密码不能为空"); } }
|
3、控制层业务方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.bitzh.controller;
import com.bitzh.entity.Student; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping;
@Controller @RequestMapping("/validate") public class ValidatetorHandler {
@GetMapping("/login") public String login(Model model){ model.addAttribute(new Student()); return "login"; }
@PostMapping("/login") public String login(@Validated Student student, BindingResult bindingResult){ if(bindingResult.hasErrors()){ return "login"; } return "success"; } }
|
4、springmvc.xml中配置validator
1 2
| <mvc:annotation-driven validator="studentValidator"></mvc:annotation-driven> <bean id="studentValidator" class="com.bitzh.validation.StudentValidation"></bean>
|
5、jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <%-- Created by IntelliJ IDEA. User: pc Date: 2024/8/4 Time: 3:10 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <html> <head> <title>Title</title> </head> <body> <h1>学生登录</h1> <form:form modelAttribute="student" action="/validate/login" method="post"> 学生姓名:<form:input path="name"></form:input><form:errors path="name"></form:errors> <br/> 学生密码:<form:input path="password"></form:input><form:errors path="password"></form:errors><br/> <input type="submit" value="提交"> </form:form>
</body> </html>
|
这里不能直接写form表单因为会不生效,要有一个GET模型将form表单中的数据自动绑定到我们学生类的变量中,然后才能进行数据校验,所以一开始用了GetMapping来动态绑定对应变量,并且在JSP中用了标签库
Annotation JSR-303标准(推荐)
Hibernater Validator,通过注解完成校验规则的绑定。
@Null 只能为null
@NotNull 不能为null
@Size 设置数据长度
@NotEmpty 不能为空
String str= null;
String str = “”;这是空
1、pom.xml导入依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.2.0.Final</version> </dependency> <dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> <version>3.0.2</version> </dependency> <dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> <version>3.3.0.Final</version> </dependency>
<dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0.1</version> </dependency> <dependency> <groupId>jakarta.activation</groupId> <artifactId>jakarta.activation-api</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>4.0.5</version> </dependency>
|
2、创建实体类,通过注解的方式给属性指定校验规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.bitzh.entity;
import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; import lombok.Data; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotEmpty;
@Data public class Account { @NotEmpty(message = "用户名不能为空") private String name; @Size(min = 6,max = 20,message = "密码长度为6-20位") private String password; @Email(regexp = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$", message = "请输入正确的邮箱") private String email; @Pattern(regexp = "/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$/",message = "请输入正确的电话格式") private String phone;
}
|
3、业务方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @GetMapping("/register") public String register(Model model){ model.addAttribute(new Account()); return "register"; } @PostMapping("/register") public String register(@Valid Account account,BindingResult bindingResult){ if(bindingResult.hasErrors()){ return "register"; } return "success"; }
|
4、配置springmvc.xml
1
| <mvc:annotation-driven></mvc:annotation-driven>
|
5、register.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <%-- Created by IntelliJ IDEA. User: pc Date: 2024/8/4 Time: 4:10 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <html> <head> <title>Title</title> </head> <body> <h1>用户注册</h1> <form:form modelAttribute="account" action="/validate/register"> 用户名:<form:input path="name"></form:input><form:errors path="name"></form:errors> <br/> 密码:<form:input path="password"></form:input><form:errors path="password"></form:errors><br/> 邮箱:<form:input path="email"></form:input><form:errors path="email"></form:errors><br/> 电话:<form:input path="phone"></form:input><form:errors path="phone"></form:errors><br/> <input type="submit" value="提交"> </form:form>
</body> </html>
|
Spring MVC表单标签库
为什么要使用表单标签库,为了实现快速开发,
1、创建Student实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.bitzh.entity2;
import lombok.Data;
@Data public class Student { private Integer id; private String name; private Integer age; private String gender; }
|
2、Handler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.bitzh.controller;
import com.bitzh.entity.Student; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping;
@Controller @RequestMapping("/student") public class StudentHandler { @RequestMapping("/get") public String get(Model model){ Student student = new Student(); model.addAttribute("student",student); return "student"; } }
|
3、JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <%-- Created by IntelliJ IDEA. User: pc Date: 2024/8/4 Time: 13:15 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <html> <head> <title>Title</title> </head> <body> <h1>修改学生信息</h1> <form action="" method="post"> 学生编号:<input type="text" name="id" value="${student.id}" readonly/><br/> 学生姓名:<input type="text" name="name" value="${student.name}"><br/> 学生年龄:<input type="text" name="age" value="${studnet.age}"<br/> 学生性别:<input type="text" name="gender" value="${student.gender}"><br/> <input type="submit" value="提交"/> </form> </body> </html>
|
使用Spring MVC表单标签可以直接将业务数据绑定到JSP表单中,非常简单。
表单标签库的使用
1、JSP页面中导入Spring MVC 表单标签库。
1
| <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
2、将form表单与业务数据进行绑定,通过ModelAttribute属性完成绑定,将modelAttribute的值设置为控制器向model对象存值时的name即可。
1 2 3 4 5 6 7 8
| <form:form modelAttribute="student" action="/student/update" method="post"> 学生编号:<form:input path="id"></form:input><br/> 学生姓名:<form:input path="name"></form:input><br/> 学生年龄:<form:input path="age"></form:input><br/> 学生性别:<form:input path="gender"></form:input><br/> <input type="submit" value="提交"/>
</form:form>
|
常用标签
1、form标签
1
| <form:form modelAttribute="student" method="post"></form:form>
|
渲染的是HTML中的form标签,通过modelAttribute属性绑定具体的业务数据。
2、input标签
1
| <form:input path="name"></form:input>
|
渲染的是HTML中的
。form标签绑定的是业务数据,input标签绑定的是业务数据中的属性值,通过path与业务数据的属性名对应,支持级联
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.bitzh.entity2;
import lombok.Data;
@Data public class Address { private Integer id; private String name;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.bitzh.entity2;
import lombok.Data;
@Data public class Student { private Integer id; private String name; private Integer age; private String gender; private Address address; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package com.bitzh.controller;
import com.bitzh.entity2.Address; import com.bitzh.entity2.Student; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping;
@Controller @RequestMapping("/student") public class StudentHandler {
@RequestMapping("/get") public String get(Model model){ Student student = new Student(); student.setId(1); student.setName("张三"); student.setAge(22); student.setGender("男"); Address address = new Address(); address.setId(1); address.setName("科技路"); student.setAddress(address); model.addAttribute("student",student); return "student2"; }
@PostMapping("/update") public String update(Student student){ System.out.println(student); return "student2"; } }
|
1 2 3 4 5 6 7 8 9
| <form:form modelAttribute="student" action="/student/update" method="post"> 学生编号:<form:input path="id"></form:input><br/> 学生姓名:<form:input path="name"></form:input><br/> 学生年龄:<form:input path="age"></form:input><br/> 学生性别:<form:input path="gender"></form:input><br/> 学生地址:<form:input path="address.name"></form:input><br/> <input type="submit" value="提交"/>
</form:form>
|
3、password标签
1
| <form:password path="password"></form:password>
|
渲染的是HTML中的
1
| <Input type = “password"/>
|
,通过path与业务数据的属性名对应,password标签的值不会在页面显示。
4、checkbox标签
1
| <form:checkbox path="hobby" value="读书"></form:checkbox>
|
渲染的是HTML中的
1
| <Input type="checkbox"/>
|
,通过path与业务数据的属性名对应,可以绑定boolean,数组和集合。
如果绑定boolean类型的变量,该变量值为true,则表示选中,false表述不选中
1
| checkbox:<form:checkbox path="flag" value="1"></form:checkbox>
|
如果绑定数组和集合,集合中的元素等于checkbox的value值,则该项选中,否则不选中。
1 2 3 4 5 6
| student.setHobby(Arrays.asList("读书","看电影","旅行"));
<form:checkbox path="hobby" value="读书"></form:checkbox>读书<br/> <form:checkbox path="hobby" value="看电影"></form:checkbox>看电影<br/> <form:checkbox path="hobby" value="打游戏"></form:checkbox>打游戏<br/> <form:checkbox path="hobby" value="旅行"></form:checkbox>旅行<br/>
|
5、checkboxs标签
1
| <form:checkbox items="${student.hobby}" path="selectHobby"></form:checkbox>
|
渲染的是HTML中的一组
1
| <input type="checkbox"/>
|
,这里需要结合items和path两个属性来使用,items绑定被遍历的集合或数组,path绑定的选中的集合或数组
items是全部选型,path为默认选中的选型。
1 2 3 4
| student.setHobby(Arrays.asList("读书","看电影","打游戏","听音乐","旅行")); student.setSelectHobby(Arrays.asList("读书","看电影"));
<form:checkboxes path="selectHobby" items="${student.hobby}"></form:checkboxes>
|
path可以直接绑定业务数据的属性,items需要通过EL表达式从域对象中取值,不能直接写属性名。
6、radiobutton标签
1
| <form:radiobutton path="radioId" value="0"></form:radionbutton>
|
渲染的是HTML中的一个
办公的数据与标签的value值相等为选中状态,否则是不选中。
1 2 3 4
| student.setRadioId(1);
<form:radiobutton path="radioId" value="0"></form:radiobutton>男 <form:radiobutton path="radioId" value="1"></form:radiobutton>女
|
7、radiobuttons标签
1
| <form:radiobuttons items:${student.grade}" path="selectGrade"></form:radiobuttons>
|
渲染的是HTML中的一组
。这里需要结合items和path,items绑定被遍历的集合或数组,path绑定被选中的值。
1 2 3 4 5 6 7 8 9 10
| Map<Integer,String> gradeMap = new HashMap<>(); gradeMap.put(1,"一年级"); gradeMap.put(2,"二年级"); gradeMap.put(3,"三年级"); gradeMap.put(4,"四年级"); gradeMap.put(5,"五年级"); student.setGradeMap(gradeMap); student.setSelectGrade(3);
<form:radiobuttons path="selectGrade" items="${student.gradeMap}"></form:radiobuttons>
|
8、select标签
1
| <form:select items="${student.citys}" path="selectCity"/>
|
渲染的是HTML中的
,这里需要结合items和path两个属性来使用,items绑定被遍历的集合或数组,path绑定被选中的值,用法和radiobuttons标签一致。
1 2 3 4 5 6 7 8 9
| Map<Integer ,String> cityMap = new HashMap<>(); cityMap.put(1,"北京"); cityMap.put(2,"上海"); cityMap.put(3,"广州"); cityMap.put(4,"深圳"); student.setCityMap(cityMap); student.setSelectCity(2);
<form:select path="selectCity" items="${student.cityMap}"></form:select>
|
9、form:select标签结合form:options使用
form:select只定义path属性,在form:select标签内部添加一个子标签form:options,然后设置items属性。
1 2 3
| <form:select path="selectCity"> <form:options items="${student.cityMap}"></form:options> </form:select>
|
10、form:select标签结合form:option使用
form:select来定义path属性,给每一个form:option都设置value属性,path与哪个value相等就默认选中该项。
1 2 3 4 5
| <form:select path="selectCity"> <form:option value="1">西安</form:option> <form:option value="2">杭州</form:option> <form:option value="3">成都</form:option> </form:select>
|
Spring MVC 国际化
国际化是指同一个应用程序在不同语言设置的浏览器中,自动显示不同的语言,Spring MVC对国际化操作做了很好的继承,我们只需要简单配置即可实现国际化。
1、springmvc.xml中配置国际化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:language"></property> <property name="useCodeAsDefaultMessage" value="true"></property> </bean> <mvc:interceptors> <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> <property name="paramName" value="lang"></property> </bean> </mvc:interceptors> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
|
2、创建国际化资源文件,language_en_US_properties,language_zh_CN_properties,分别存储英文和中文资源。
1 2 3 4 5 6 7 8 9 10
| language.cn = \u4E2D\u6587 language.en = English info = \u767B\u5F55 username = \u7528\u6237\u540D password = \u5BC6\u7801 repassword = \u786E\u8BA4\u5BC6\u7801 tel = \u7535\u8BDD email = \u7535\u5B50\u90AE\u7BB1 submit = \u63D0\u4EA4 reset = \u91CD\u7F6E
|
1 2 3 4 5 6 7 8 9 10
| language.cn = \u4E2D\u6587 language.en = English info = login username = username password = password repassword = repassword tel = tel email = email submit = submit reset = reset
|
3、创建Handler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.bitzh.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping;
@Controller @RequestMapping("/inter") public class InterHandler { @GetMapping("/index") public String index(){ return "inter"; } }
|
4、JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <%-- Created by IntelliJ IDEA. User: pc Date: 2024/8/4 Time: 15:55 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <html> <head> <title>Title</title> </head> <body> <h1><spring:message code="info"></spring:message></h1>
<a href="index?lang=en_US">English</a> <a href="index?lang=zh_CN">中文</a> <form> <spring:message code="username"/>:<input type="text"/><br/> <spring:message code="password"/>:<input type="password"/><br/> <spring:message code="repassword"/>:<input type="password"/><br/> <spring:message code="tel"/>:<input type="text"/><br/> <spring:message code="email"/><input type="text"/><br/> <input type="submit" value="<spring:message code="submit"/>"/> <input type="reset" value="<spring:message code="reset"/>"/>
</form>
</body> </html>
|