Spring基础知识(15)- Spring MVC (五)


表单标签库、数据校验


1. 表单标签库

    进行 Spring MVC 项目开发时,一般会使用 EL 表达式和 JSTL 标签来完成页面视图的开发。其实 Spring 也有自己的一套表单标签库,通过 Spring 表单标签,可以很容易地将模型数据中的命令对象绑定到 HTML 表单元素中。

    和 JSTL 标签的使用方法相同,在使用 Spring 表单标签之前,必须在 JSP 页面开头处声明 taglib 指令,指令代码如下。

        <%@ taglib uri="http://www.springframework.org/tags/form" prefix="fm" %>

    常用的 Spring 表单标签如下表所示。

名称 作用
form 渲染表单元素
input 输入框组件标签,渲染 元素
password 密码框组件标签,渲染 元素
hidden 隐藏框组件标签,渲染 元素
textarea 多行输入框组件标签,渲染 textarea 元素
checkbox 复选框组件标签,渲染一个 元素
checkboxes 渲染多个 元素
radiobutton 单选框组件标签,渲染一个 元素
radiobuttons 渲染多个 元素
select 下拉列表组件标签,渲染一个选择元素
option 渲染一个选项元素
options 渲染多个选项元素
errors 显示表单数据校验所对应的错误信息


    以上标签基本都拥有以下属性。

        path:属性路径,表示表单对象属性,如 userName、userCode 等。
        cssClass:表单组件对应的 CSS 样式类名。
        cssErrorClass:当提交表单后报错(服务端错误),采用的 CSS 样式类。
        cssStyle:表单组件对应的 CSS 样式。
        htmlEscape:绑定的表单属性值是否要对 HTML 特殊字符进行转换,默认为 true。

    示例

        在 “” 的示例里,更新过 springmvc-beans.xml 的 SpringmvcBasic 项目基础上,修改如下。


        (1) 使用 src/main/java/com/example/entity/User.java 文件

 1             package com.example.entity;
 2 
 3             public class User {
 4                 private int id;
 5                 private String username;
 6                 private String password;
 7 
 8                 public User() {
 9 
10                 }
11 
12                 public int getId() {
13                     return id;
14                 }
15 
16                 public void setId(int id) {
17                     this.id = id;
18                 }
19 
20                 public String getUsername() {
21                     return this.username;
22                 }
23 
24                 public void setUsername(String username) {
25                     this.username = username;
26                 }
27 
28                 public String getPassword() {
29                     return password;
30                 }
31 
32                 public void setPassword(String password) {
33                     this.password = password;
34                 }
35             }


        (2) View

            创建 src/main/webapp/WEB-INF/jsp/user_add.jsp 文件

 1                 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
 2                 <%@ taglib uri="http://www.springframework.org/tags/form" prefix="fm" %>
 3                 
 4                 
 5                     "Content-Type" content="text/html; charset=UTF-8">
 6                     Add User
 7                 
 8                 
 9 
10                     

Add User

11 "POST" modelAttribute="user" action="${pageContext.request.contextPath }/user/show"> 12 131415161718192021222526
"username">Username: "username" value="admin" />
"password">Password: "password" value="123456" />
"2"> 23 "submit" value="Submit"/> 24
27
28 29 30


            标签的 modelAttribute 属性用于指定绑定的模型属性。默认从模型中尝试取名为 “command” 的表单对象,若不存在此表单对象,将会报错。所以一般情况下会指定 modelAttribute 属性。

            此外,表单组件标签页拥有 HTML 标签的各种属性,如 id、onclick 等,都可以根据需要灵活使用。

            创建 src/main/webapp/WEB-INF/jsp/user_show.jsp 文件

 1                 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
 2                 
 3                 
 4                     "Content-Type" content="text/html; charset=UTF-8">
 5                     Show User
 6                 
 7                 
 8                     

Your account info:

9 10

Username: ${user.username }

11

Password: ${user.password }

12 13


        (3) 修改 src/main/java/com/example/controller/UserController.java 文件

 1             package com.example.controller;
 2 
 3             import org.springframework.stereotype.Controller;
 4             import org.springframework.web.bind.annotation.ModelAttribute;
 5             import org.springframework.web.bind.annotation.RequestMapping;
 6             import org.springframework.web.bind.annotation.RequestMethod;
 7 
 8             import com.example.entity.User;
 9 
10             @Controller
11             @RequestMapping("/user")
12             public class UserController {
13 
14                 @RequestMapping(value = "/add", method = RequestMethod.GET)
15                 public String userAdd(@ModelAttribute("user") User user) {
16                     return "user_add";
17                 }
18 
19                 @RequestMapping(value = "/show", method = RequestMethod.POST)
20                 public String userShow(User user) {
21                     return "user_show";
22                 }
23 
24                 ...
25             }


        访问:http://localhost:9090/user/add


2. 数据校验

    一般情况下,用户的输入是随意的,为了保证数据的合法性,数据验证是所有 Web 应用必须处理的问题。

    Spring MVC 有以下两种方法可以验证输入:

        (1) 利用 Spring 自带的验证框架
        (2) 利用 JSR 303 实现

    数据验证分为客户端验证和服务器端验证,客户端验证主要是过滤正常用户的误操作,通过 JavaScript 代码完成。服务器端验证是整个应用阻止非法数据的最后防线,通过在应用中编程实现。本文使用 JSR 303 实现服务器端的数据验证。

    JSR 303 是 Java 为 Bean 数据合法性校验所提供的标准框架。JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证。可以通过 https://jcp.org/en/jsr/detail?id=303 查看详细内容并下载 JSR 303 Bean Validation。

    JSR 303 不需要编写验证器,它定义了一套可标注在成员变量、属性方法上的校验注解,如下表所示。

名称 说明
@Null 被标注的元素必须为 null
@NotNull 被标注的元素必须不为 null
@AssertTrue 被标注的元素必须为 true
@AssertFalse 被标注的元素必须为 false
@Min(value) 被标注的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被标注的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMax(value) 被标注的元素必须是一个数字,其值必须大于等于指定的最大值
@DecimalMin(value) 被标注的元素必须是一个数字,其值必须小于等于指定的最小值
@size 被标注的元素的大小必须在指定的范围内
@Digits(integer,fraction) 被标注的元素必须是一个数字,其值必须在可接受的范围内;integer 指定整数精度,fraction 指定小数精度
@Past 被标注的元素必须是一个过去的日期
@Future 被标注的元素必须是一个将来的日期
@Pattern(value) 被标注的元素必须符合指定的正则表达式


    Spring MVC 支持 JSR 303 标准的校验框架,Spring 的 DataBinder 在进行数据绑定时,可同时调用校验框架来完成数据校验工作,非常简单方便。在 Spring MVC 中,可以直接通过注解驱动的方式来进行数据校验。

    Spring 本身没有提供 JSR 303 的实现,Hibernate Validator 实现了 JSR 303,所以必须在项目中加入 Hibernate Validator 库。

   

    示例

        在 “” 的示例里,更新过 springmvc-beans.xml 的 SpringmvcBasic 项目基础上,修改如下。


      (1) 导入 validation-api, hibernate-validator 依赖包

            访问 http://www.mvnrepository.com/,查询 validation-api, hibernate-validator

          修改 pom.xml:

            
                ...

                

                    ...

                    
                    
                        org.hibernate
                        hibernate-validator
                        5.1.0.Final
                    
                    
                    
                        javax.validation
                        validation-api
                        1.1.0.Final
                    

                    ...

                

                ...    

            

            在IDE中项目列表 -> SrpingmvcBasic -> 点击鼠标右键 -> Maven -> Reload Project

        (2) 创建 src/main/java/com/example/entity/User.java 文件

 1             package com.example.entity;
 2 
 3             import javax.validation.constraints.NotNull;
 4             import org.hibernate.validator.constraints.Email;
 5             import org.hibernate.validator.constraints.Length;
 6 
 7             public class User {
 8                 private int id;
 9                 @NotNull
10                 @Length(min=2, max=8, message="Username 2 < length < 8")
11                 private String username;
12                 @NotNull(message="Password is required")
13                 private String password;
14                 @Email(regexp="[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]", message="Invalid email format")
15                 private String email;
16 
17                 public User() {
18 
19                 }
20 
21                 public int getId() {
22                     return id;
23                 }
24 
25                 public void setId(int id) {
26                     this.id = id;
27                 }
28 
29                 public String getUsername() {
30                     return this.username;
31                 }
32 
33                 public void setUsername(String username) {
34                     this.username = username;
35                 }
36 
37                 public String getPassword() {
38                     return password;
39                 }
40 
41                 public void setPassword(String password) {
42                     this.password = password;
43                 }
44 
45                  public String getEmail() {
46                     return email;
47                 }
48 
49                 public void setEmail(String email) {
50                     this.email = email;
51                 }               
52             }


        (3) 创建 src/main/webapp/WEB-INF/jsp/user_add2.jsp 文件

 1             <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
 2             
 3             
 4                 "Content-Type" content="text/html; charset=UTF-8">
 5                 Add User (<span style="color: rgba(128, 0, 128, 1)">2</span>)
 6             
 7             
 8 
 9                 

Add User (2)

10
"POST" action="${pageContext.request.contextPath }/user/add2/post"> 11 12131415161718192021222324252829
Username: "username" value="admin" />
Password: "password" value="123456" />
Email: "email" value="username@test.com" />
"2"> 26 "submit" value="Submit"/> 27
30
31 32 33


        (4) 修改 src/main/java/com/example/controller/UserController.java 文件

 1             package com.example.controller;
 2 
 3             import java.util.List;
 4             import javax.validation.Valid;
 5 
 6             import org.springframework.validation.BindingResult;
 7             import org.springframework.validation.ObjectError;
 8 
 9             import org.springframework.stereotype.Controller;
10             import org.springframework.ui.Model;
11             import org.springframework.web.bind.annotation.RequestMapping;
12             import org.springframework.web.bind.annotation.RequestMethod;
13 
14             import com.example.entity.User;
15 
16             @Controller
17             @RequestMapping("/user")
18             public class UserController {
19 
20                 @RequestMapping(value = "/add2", method = RequestMethod.GET)
21                 public String add2() {
22                     return "user_add2";
23                 }
24 
25                 @RequestMapping(value = "/add2/post", method = RequestMethod.POST)
26                 public String add2Post(@Valid User user, BindingResult result, Model model) {
27 
28                     if (result.hasErrors()) {
29                         List errors = result.getAllErrors();
30 
31                         String str = "
"; 32 for (ObjectError error : errors) { 33 str += error.getDefaultMessage(); 34 str += "
"; 35 } 36 37 model.addAttribute("message", str); 38 return "failed"; 39 } else { 40 model.addAttribute("message", "Add user success"); 41 return "success"; 42 } 43 } 44 45 }


        访问:http://localhost:9090/user/add2