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 输入框组件标签,渲染 <input type="text"/> 元素
password 密码框组件标签,渲染 <input type="password"/> 元素
hidden 隐藏框组件标签,渲染 <input type="hidden"/> 元素
textarea 多行输入框组件标签,渲染 textarea 元素
checkbox 复选框组件标签,渲染一个 <input type="checkbox"/> 元素
checkboxes 渲染多个 <input type="checkbox"/> 元素
radiobutton 单选框组件标签,渲染一个 <input type="radio"/> 元素
radiobuttons 渲染多个 <input type="radio"/> 元素
select 下拉列表组件标签,渲染一个选择元素
option 渲染一个选项元素
options 渲染多个选项元素
errors 显示表单数据校验所对应的错误信息


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

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

    示例

        在 “Spring基础知识(12)- Spring MVC (二)” 的示例里,更新过 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                 <html>
 4                 <head>
 5                     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6                     <title>Add User</title>
 7                 </head>
 8                 <body>
 9 
10                     <h4>Add User</h4>
11                     <fm:form method="POST" modelAttribute="user" action="${pageContext.request.contextPath }/user/show">
12                     <table>
13                         <tr>
14                             <td><fm:label path="username">Username:</fm:label></td>
15                             <td><fm:input path="username" value="admin" /></td>
16                         </tr>
17                         <tr>
18                             <td><fm:label path="password">Password:</fm:label></td>
19                             <td><fm:input path="password" value="123456" /></td>
20                         </tr>
21                         <tr>
22                             <td colspan="2">
23                                 <input type="submit" value="Submit"/>
24                             </td>
25                         </tr>
26                     </table>
27                     </fm:form>
28 
29                 </body>
30                 </html>


            <fm:form> 标签的 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                 <html>
 3                 <head>
 4                     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 5                     <title>Show User</title>
 6                 </head>
 7                 <body>
 8                     <p>Your account info: </p>
 9                     <!-- 使用 EL 表达式取出 model 中的 user 信息 -->
10                     <p>Username: ${user.username }</p>
11                     <p>Password: ${user.password }</p>
12                 </body>
13                 </html>


        (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 库。

   

    示例

        在 “Spring基础知识(12)- Spring MVC (二)” 的示例里,更新过 springmvc-beans.xml 的 SpringmvcBasic 项目基础上,修改如下。


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

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

          修改 pom.xml:

            <project ... >
                ...

                <dependencies>

                    ...

                    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
                    <dependency>
                        <groupId>org.hibernate</groupId>
                        <artifactId>hibernate-validator</artifactId>
                        <version>5.1.0.Final</version>
                    </dependency>
                    <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
                    <dependency>
                        <groupId>javax.validation</groupId>
                        <artifactId>validation-api</artifactId>
                        <version>1.1.0.Final</version>
                    </dependency>

                    ...

                </dependencies>

                ...    

            </project>

 

            在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             <html>
 3             <head>
 4                 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 5                 <title>Add User (2)</title>
 6             </head>
 7             <body>
 8 
 9                 <h4>Add User (2)</h4>
10                 <form method="POST" action="${pageContext.request.contextPath }/user/add2/post">
11                 <table>
12                     <tr>
13                         <td>Username:</td>
14                         <td><input name="username" value="admin" /></td>
15                     </tr>
16                     <tr>
17                         <td>Password:</td>
18                         <td><input name="password" value="123456" /></td>
19                     </tr>
20                     <tr>
21                         <td>Email:</td>
22                         <td><input name="email" value="username@test.com" /></td>
23                     </tr>
24                     <tr>
25                         <td colspan="2">
26                             <input type="submit" value="Submit"/>
27                         </td>
28                     </tr>
29                 </table>
30                 </form>
31 
32             </body>
33             </html>


        (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<ObjectError> errors = result.getAllErrors();
30 
31                         String str = "<br>";
32                         for (ObjectError error : errors) {
33                             str += error.getDefaultMessage();
34                             str += "<br>";
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

posted @ 2022-03-30 13:07  垄山小站  阅读(359)  评论(0)    收藏  举报