欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringMVC实现表单验证功能详解

程序员文章站 2024-04-02 08:51:34
本章节内容很丰富,主要有基本的表单操作,数据的格式化,数据的校验,以及提示信息的国际化等实用技能。 首先看效果图 项目结构图 接下来用代码重点学习spring...

本章节内容很丰富,主要有基本的表单操作,数据的格式化,数据的校验,以及提示信息的国际化等实用技能。
首先看效果图

SpringMVC实现表单验证功能详解

项目结构图

SpringMVC实现表单验证功能详解

接下来用代码重点学习springmvc的表单操作,数据格式化,数据校验以及错误提示信息国际化。请读者将重点放在usercontroller.java,user.java,input.jsp三个文件中。
maven 项目必不可少的pom.xml文件。里面有该功能需要的所有jar包。

<?xml version="1.0" encoding="utf-8"?> 
<project xmlns="http://maven.apache.org/pom/4.0.0" 
 xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" 
 xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
 <modelversion>4.0.0</modelversion> 
 <groupid>com.springmvc</groupid> 
 <artifactid>springmvc</artifactid> 
 <version>0.0.1-snapshot</version> 
 <packaging>war</packaging> 
 
 <!-- 若不配置,打包时会提示错误信息 
 failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project springmvc: compilation failure: 
 提示 未结束的字符串文字 ,若字符串后面加上空格后可以打包成功,但会乱码。 
 原因是:maven使用的是默认的compile插件来进行编译的。complier是maven的核心插件之一,然而complier插件默认只支持编译java 1.4 
 --> 
 <build> 
 <plugins> 
  <plugin> 
   <artifactid>maven-compiler-plugin</artifactid> 
   <configuration> 
    <source>1.7</source> 
    <target>1.7</target> 
    <encoding>utf-8</encoding> 
   </configuration> 
  </plugin> 
 </plugins> 
 </build> 
 
 <properties> 
 <spring.version>4.1.3.release</spring.version> 
 </properties> 
 <dependencies> 
 <!-- spring begin --> 
 <dependency> 
  <groupid>org.springframework</groupid> 
  <artifactid>spring-webmvc</artifactid> 
  <version>${spring.version}</version> 
 </dependency> 
 
 <dependency> 
  <groupid>org.springframework</groupid> 
  <artifactid>spring-context</artifactid> 
  <version>${spring.version}</version> 
 </dependency> 
 
 <dependency> 
  <groupid>org.springframework</groupid> 
  <artifactid>spring-aop</artifactid> 
  <version>${spring.version}</version> 
 </dependency> 
 
 <dependency> 
  <groupid>org.springframework</groupid> 
  <artifactid>spring-core</artifactid> 
  <version>${spring.version}</version> 
 </dependency> 
  
 <dependency> 
  <groupid>org.springframework</groupid> 
  <artifactid>spring-web</artifactid> 
  <version>${spring.version}</version> 
 </dependency> 
 
 <!-- spring end --> 
 <dependency> 
  <groupid>javax.servlet</groupid> 
  <artifactid>javax.servlet-api</artifactid> 
  <version>4.0.0</version> 
  <scope>provided</scope> 
 </dependency> 
 <dependency> 
  <groupid>javax.servlet</groupid> 
  <artifactid>jstl</artifactid> 
  <version>1.2</version> 
 </dependency> 
 <dependency> 
  <groupid>taglibs</groupid> 
  <artifactid>standard</artifactid> 
  <version>1.1.2</version> 
 </dependency> 
 <!-- 缺少jsp-api 则提示 javax.servlet.jsp.jspexception cannot be resolved to a type --> 
 <dependency> 
  <groupid>javax.servlet.jsp</groupid> 
  <artifactid>jsp-api</artifactid> 
  <version>2.2</version> 
  <scope>provided</scope> 
 </dependency> 
 <!-- jsr 303 start --> 
 <dependency> 
  <groupid>org.hibernate</groupid> 
  <artifactid>hibernate-validator</artifactid> 
  <version>5.4.1.final</version> 
 </dependency> 
 <dependency> 
  <groupid>javax.validation</groupid> 
  <artifactid>validation-api</artifactid> 
  <version>1.1.0.final</version> 
 </dependency> 
 <!-- jsr 303 end --> 
   
 </dependencies> 
</project> 

springmvc的核心配置文件

<?xml version="1.0" encoding="utf-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" 
 xmlns:context="http://www.springframework.org/schema/context" 
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 
  http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> 
 
 <!-- 配置自定扫描的包 --> 
 <context:component-scan base-package="com.itdragon.springmvc" /> 
 
 <!-- 配置视图解析器 --> 
 <bean class="org.springframework.web.servlet.view.internalresourceviewresolver"> 
  <property name="prefix" value="/web-inf/views/"></property> 
  <property name="suffix" value=".jsp"></property> 
 </bean> 
  
 <!-- 配置注解驱动 --> 
 <mvc:annotation-driven /> 
 
 <!-- 配置视图 beannameviewresolver 解析器 
  使用视图的名字来解析视图 
  通过 order 属性来定义视图解析器的优先级, order 值越小优先级越高 
 --> 
 <bean class="org.springframework.web.servlet.view.beannameviewresolver"> 
  <property name="order" value="100"></property> 
 </bean> 
  
 <!-- 配置直接跳转的页面,无需经过controller层 
  http://localhost:8080/springmvc/index 
  然后会跳转到 web-inf/views/index.jsp 页面 
 --> 
 <mvc:view-controller path="/index" view-name="index"/> 
  
 <mvc:default-servlet-handler/> 
  
 <!-- 配置国际化资源文件 --> 
 <bean id="messagesource" 
  class="org.springframework.context.support.resourcebundlemessagesource"> 
  <property name="basename" value="i18n"></property> 
 </bean> 
  
</beans> 

以上是准备工作。下面开始核心代码介绍。

数据的校验思路:

第一步,在实体类中指定属性添加校验注解(如@notempty),
第二步,在控制层目标方法实体类参数添加注解@valid,
第三步,在返回页面加上显示提示错误信息

数据格式化思路:只需要在实体类中加上注解即可。

信息国际化思路:

第一步,在springmvc配置文件中配置国际化资源文件
第二步,创建文件i18n_zh_cn.properties文件
第三步,在i18n_zh_cn.properties文件配置国际化信息(要严格按照springmvc的语法)

usercontroller.java,两个重点知识。一个是springmvc的rest风格的增删改查。另一个是@valid注解用法。具体看代码。

import java.util.map; 
import javax.validation.valid; 
import org.springframework.beans.factory.annotation.autowired; 
import org.springframework.stereotype.controller; 
import org.springframework.validation.errors; 
import org.springframework.validation.fielderror; 
import org.springframework.web.bind.annotation.modelattribute; 
import org.springframework.web.bind.annotation.pathvariable; 
import org.springframework.web.bind.annotation.requestmapping; 
import org.springframework.web.bind.annotation.requestmethod; 
import org.springframework.web.bind.annotation.requestparam; 
 
import com.itdragon.springmvc.crud.dao.positiondao; 
import com.itdragon.springmvc.crud.dao.userdao; 
import com.itdragon.springmvc.crud.orm.user; 
 
@controller 
public class usercontroller { 
 
 @autowired 
 private userdao userdao; 
  
 @autowired 
 private positiondao positiondao; 
  
 private static final string input = "input"; // 跳转到编辑页面 
 
 private static final string list = "list"; // 跳转到用户列表页面 
 
 @modelattribute 
 public void getuser(@requestparam(value="id",required=false) integer id, 
   map<string, object> map){ 
  if(id != null){ 
   map.put("user", userdao.getuserbyid(id)); 
  } 
 } 
  
 // 更新用户,用put请求方式区别get请求方式,属于springmvc rest 风格的crud 
 @requestmapping(value="/user", method=requestmethod.put) 
 public string updateuser(user user){ 
  userdao.save(user); 
  return "redirect:/users"; 
 } 
  
 // 点击编辑跳转编辑页面 
 @requestmapping(value="/user/{id}", method=requestmethod.get) 
 public string input(@pathvariable("id") integer id, map<string, object> map){ 
  map.put("user", userdao.getuserbyid(id)); 
  map.put("positions", positiondao.queryallpositions()); 
  return input; 
 } 
  
 // 通过id删除用户 
 @requestmapping(value="/delete/{id}", method=requestmethod.get) 
 public string delete(@pathvariable("id") integer id){ 
  userdao.deleteuserbyid(id); 
  return "redirect:/users"; 
 } 
  
 /** 
  * 新增用户,若保存成功则跳转到用户列表页面,若失败则跳转到编辑页面 
  * @param user 用 @valid 注解修饰后,可实现数据校验的逻辑 
  * @param result 数据校验结果 
  * @param map 数据模型 
  * @return 
  */ 
 @requestmapping(value="/user", method=requestmethod.post) 
 public string save(@valid user user, errors result, map<string, object> map){ 
  if(result.geterrorcount() > 0){ 
   for(fielderror error : result.getfielderrors()){ 
    system.out.println(error.getfield() + " : " + error.getdefaultmessage()); 
   } 
   map.put("positions", positiondao.queryallpositions()); 
   return input; 
  } 
  userdao.save(user); 
  return "redirect:/users"; 
 } 
  
 @requestmapping(value="/user", method=requestmethod.get) 
 public string input(map<string, object> map){ 
  map.put("positions", positiondao.queryallpositions()); 
  map.put("user", new user()); 
  return input; 
 } 
  
 // 跳转用户列表页面 
 @requestmapping("/users") 
 public string list(map<string, object> map){ 
  map.put("users", userdao.queryallusers()); 
  return list; 
 } 
  
} 

user.java,两个重点知识。一个是数据的格式化(包括日期格式化和数值格式化)。另一个是使用 jsr 303 验证标准数据校验。

数据格式化,由于前端传给后台的是字符串,对于比较特殊的属性,比如date,float类型就需要进行数据格式化
** @numberformat 数值格式化 **
可以格式化/解析的数字类型:short、integer、long、float、double、bigdecimal、biginteger。
属性参数有:pattern="###,###.##"(重点)。
style= org.springframework.format.annotation.numberformat.style.number(currency / percent)。其中style.number(通用样式,默认值);style.currency(货币样式);style.percent(百分数样式)

** @datetimeformat 日期格式化 **
可以格式化/解析的数字类型:java.util.date 、java.util.calendar 、java.long.long。
属性参数有:pattern="yyyy-mm-dd hh:mm:ss"(重点)。
iso=指定解析/格式化字段数据的iso模式,包括四种:iso.none(不使用iso模式,默认值),iso.date(yyyy-mm-dd),iso.time(hh:mm:ss.sssz),iso.date_time(yyyy-mm-dd hh:mm:ss.sssz);style=指定用于格式化的样式模式,默认“ss”,优先级: pattern 大于 iso 大于 style,后两个很少用。

数据校验

空检查
** @null ** 验证对象是否为null
** @notnull ** 验证对象是否不为null, 无法查检长度为0的字符串
** @notblank ** 检查约束字符串是不是null还有被trim的长度是否大于0,只对字符串,
且会去掉前后空格
** @notempty ** 检查约束元素是否为null或者是empty
booelan检查
** @asserttrue ** 验证 boolean 对象是否为 true
** @assertfalse ** 验证 boolean 对象是否为 false
长度检查
** @size(min=, max=) ** 验证对象(array,collection,map,string)值是否在给定的范围之内
** @length(min=, max=) ** 验证对象(charsequence子类型)长度是否在给定的范围之内
日期检查
** @past ** 验证 date 和 calendar 对象是否在当前时间之前
** @future ** 验证 date 和 calendar 对象是否在当前时间之后
** @pattern ** 验证 string 对象是否符合正则表达式的规则
数值检查
** @min ** 验证 number 和 string 对象是否大等于指定的值
** @max ** 验证 number 和 string 对象是否小等于指定的值
** @decimalmax ** 被标注的值必须不大于约束中指定的最大值. 这个约束的参数
是一个通过bigdecimal定义的最大值的字符串表示.小数存在精度
** @decimalmin ** 被标注的值必须不小于约束中指定的最小值. 这个约束的参数
是一个通过bigdecimal定义的最小值的字符串表示.小数存在精度
** @digits ** 验证 number 和 string 的构成是否合法
** @digits(integer=,fraction=) ** 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度
** @range(min=, max=) ** 检查数字是否介于min和max之间
** @creditcardnumber ** 信用卡验证
** @email ** 验证是否是邮件地址,如果为null,不进行验证,算通过验证
** @scriptassert(lang= ,script=, alias=) ** 通过脚本验证

其中有几点需要注意:

空判断注解

string name  @notnull @notempty @notblank
null       false    false    false
""       true    false    false
" "       true    true    false
"itdragon!"   true    true    true

数值检查:建议使用在stirng,integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为stirng为"",integer为null

import java.util.date; 
import javax.validation.constraints.decimalmin; 
import org.hibernate.validator.constraints.email; 
import org.hibernate.validator.constraints.notempty; 
import org.springframework.format.annotation.datetimeformat; 
import org.springframework.format.annotation.numberformat; 
 
public class user { 
  
 private integer id; 
 @notempty 
 private string account; 
 @email 
 @notempty 
 private string email; 
 private integer sex; 
 private position position; 
 @datetimeformat(pattern="yyyy-mm-dd") 
 private date createddate; 
 @numberformat(pattern="###,###.#") 
 @decimalmin("2000") 
 private double salary; 
  
 public user() { 
 } 
 public user(integer id, string account, string email, integer sex, 
   position position, date createddate, double salary) { 
  this.id = id; 
  this.account = account; 
  this.email = email; 
  this.sex = sex; 
  this.position = position; 
  this.createddate = createddate; 
  this.salary = salary; 
 } 
 public integer getid() { 
  return id; 
 } 
 public void setid(integer id) { 
  this.id = id; 
 } 
 public string getaccount() { 
  return account; 
 } 
 public void setaccount(string account) { 
  this.account = account; 
 } 
 public string getemail() { 
  return email; 
 } 
 public void setemail(string email) { 
  this.email = email; 
 } 
 public integer getsex() { 
  return sex; 
 } 
 public void setsex(integer sex) { 
  this.sex = sex; 
 } 
 public position getposition() { 
  return position; 
 } 
 public void setposition(position position) { 
  this.position = position; 
 } 
 public date getcreateddate() { 
  return createddate; 
 } 
 public void setcreateddate(date createddate) { 
  this.createddate = createddate; 
 } 
 public double getsalary() { 
  return salary; 
 } 
 public void setsalary(double salary) { 
  this.salary = salary; 
 } 
 @override 
 public string tostring() { 
  return "user [id=" + id + ", account=" + account + ", email=" + email 
    + ", sex=" + sex + ", position=" + position + ", createddate=" 
    + createddate + ", salary=" + salary + "]"; 
 } 
 
} 

input.jsp,springmvc 表单标签知识点详解

<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> 
<%@page import="java.util.hashmap"%> 
<%@page import="java.util.map"%> 
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
 
<!doctype html"> 
<html> 
<head> 
<meta http-equiv="content-type" content="text/html; charset=utf-8"> 
<title>springmvc 表单操作</title> 
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="stylesheet"> 
</head> 
<body> 
 
 <!-- 
 1. 使用 form 标签可以更快速的开发出表单页面, 而且可以更方便的进行表单值的回显。 
 step1 导入标签 taglib prefix="form" uri="http://www.springframework.org/tags/form" 
 step2 和普通的form用法差不多。path 相当于 普通的form的name,form:hidden 隐藏域,form:errors 提示错误信息。 
 2. 使用form 标签需要注意: 
 通过 modelattribute 属性指定绑定的模型属性, 该数据模型必须是实例化过的。 
 若没有 modelattribute 指定该属性,则默认从 request 域对象中读取 command 的表单 bean (如果该属性值也不存在,则会发生错误)。 
 java.lang.illegalstateexception: neither bindingresult nor plain target object for bean name 'command' available as request attribute 
 --> 
 <div class="container"> 
 <div class="row"> 
  <div class="col-sm-6"> 
  <div class="panel panel-info" style="margin-top:10px;"> 
  <div class="panel-heading"> 
   <h3 class="panel-title">修改或创建用户信息</h3> 
  </div> 
  <div class="panel-body"> 
   <form:form action="${pagecontext.request.contextpath }/user" method="post" 
   modelattribute="user" class="form-horizontal" role="form"> 
   <c:if test="${user.id == null }"> 
    <!-- path 属性对应 html 表单标签的 name 属性值 --> 
    <div class="form-group"> 
    <label class="col-sm-2 control-label">account</label> 
    <div class="col-sm-10"> 
     <form:input class="form-control" path="account"/> 
     <form:errors style="color:red" path="account"></form:errors> 
    </div> 
    </div> 
   </c:if> 
   <c:if test="${user.id != null }"> 
    <form:hidden path="id"/> 
    <input type="hidden" name="_method" value="put"/> 
    <%-- 对于 _method 不能使用 form:hidden 标签, 因为 modelattribute 对应的 bean 中没有 _method 这个属性 --%> 
    <%-- 
    <form:hidden path="_method" value="put"/> 
    --%> 
   </c:if> 
   <div class="form-group"> 
    <label class="col-sm-2 control-label">email</label> 
    <div class="col-sm-10"> 
    <form:input class="form-control" path="email"/> 
    <form:errors style="color:red" path="email"></form:errors> 
    </div> 
   </div> 
   <!-- 这是springmvc 不足之处 --> 
   <% 
    map<string, string> genders = new hashmap(); 
    genders.put("1", "male"); 
    genders.put("0", "female"); 
    request.setattribute("genders", genders); 
   %> 
   <div class="form-group"> 
    <label class="col-sm-2 control-label">sex</label> 
    <div class="col-sm-10"> 
    <form:radiobuttons path="sex" items="${genders }" /> 
    </div> 
   </div> 
   <div class="form-group"> 
    <label class="col-sm-2 control-label">position</label> 
    <div class="col-sm-10"> 
    <form:select class="form-control" path="position.id" items="${positions}" itemlabel="level" itemvalue="id"> 
    </form:select> 
    </div> 
   </div> 
   <div class="form-group"> 
    <label class="col-sm-2 control-label">date</label> 
    <div class="col-sm-10"> 
    <form:input class="form-control" path="createddate"/> 
    <form:errors style="color:red" path="createddate"></form:errors> 
    </div> 
   </div> 
   <div class="form-group"> 
    <label class="col-sm-2 control-label">salary</label> 
    <div class="col-sm-10"> 
    <form:input class="form-control" path="salary"/> 
    <form:errors style="color:red" path="salary"></form:errors> 
    </div> 
   </div> 
   <input class="btn btn-success" type="submit" value="submit"/> 
   </form:form> 
  </div> 
  </div> 
  </div> 
 </div> 
 </div> 
 
</body> 
</html>

 i18n国际化文件

#语法:实体类上属性的注解.验证目标方法的modleattribute 属性值(如果没有默认为实体类首字母小写).注解修饰的属性 
#以第一个为例:user实体类中 属性account用了notempty注解修饰,表示不能为空。所以前缀是notempty 
#验证的目标方法 public string save(@valid user user, ...) user被注解@valid 修饰,但没有被modleattribute修饰。所以中间是user 
#后缀就是被注解修饰的属性名 account 
notempty.user.account=用户名不能为空 
email.user.email=email地址不合法 
 
#typemismatch 数据类型不匹配时提示 
typemismatch.user.createddate=不是一个日期 
#required 必要参数不存在时提示 
#methodinvocation 调用目标方法出错的时提示 

其他文件,position 实体类

public class position { 
 
 private integer id; 
 private string level; 
 
 public position() { 
 } 
 public position(integer id, string level) { 
 this.id = id; 
 this.level = level; 
 } 
 public integer getid() { 
 return id; 
 } 
 public void setid(integer id) { 
 this.id = id; 
 } 
 public string getlevel() { 
 return level; 
 } 
 public void setlevel(string level) { 
 this.level = level; 
 } 
 @override 
 public string tostring() { 
 return "position [id=" + id + ", level=" + level + "]"; 
 } 
} 

 模拟用户操作的dao,userdao.java

import java.util.collection; 
import java.util.date; 
import java.util.hashmap; 
import java.util.map; 
import org.springframework.beans.factory.annotation.autowired; 
import org.springframework.stereotype.repository; 
import com.itdragon.springmvc.crud.orm.position; 
import com.itdragon.springmvc.crud.orm.user; 
 
@repository 
public class userdao { 
 
 private static map<integer, user> users = null; 
 
 @autowired 
 private positiondao positiondao; 
 
 // 模拟数据库查询数据 
 static{ 
 users = new hashmap<integer, user>(); 
 users.put(1, new user(1, "itdragon", "11@xl.com", 1, new position(1, "架构师"), new date(), 18888.88)); 
 users.put(2, new user(2, "blog", "22@xl.com", 1, new position(2, "高级工程师"), new date(), 15555.55)); 
 users.put(3, new user(3, "welcome", "33@xl.com", 0, new position(3, "中级工程师"), new date(), 8888.88)); 
 users.put(4, new user(4, "to", "44@xl.com", 0, new position(4, "初级工程师"), new date(), 5555.55)); 
 users.put(5, new user(5, "you", "55@xl.com", 1, new position(5, "java实习生"), new date(), 2222.22)); 
 } 
 
 // 下一次存储的下标id 
 private static integer initid = 6; 
 
 public void save(user user){ 
 if(user.getid() == null){ 
  user.setid(initid++); 
 } 
  
 user.setposition(positiondao.getpositionbyid(user.getposition().getid())); 
 users.put(user.getid(), user); 
 } 
 
 public collection<user> queryallusers(){ 
 return users.values(); 
 } 
 
 public user getuserbyid(integer id){ 
 return users.get(id); 
 } 
 
 public void deleteuserbyid(integer id){ 
 users.remove(id); 
 } 
} 

import java.util.collection; 
import java.util.hashmap; 
import java.util.map; 
import org.springframework.stereotype.repository; 
import com.itdragon.springmvc.crud.orm.position; 
 
@repository 
public class positiondao { 
 
 private static map<integer, position> positions = null; 
 
 static{ 
 positions = new hashmap<integer, position>(); 
  
 positions.put(1, new position(1, "架构师")); 
 positions.put(2, new position(2, "高级工程师")); 
 positions.put(3, new position(3, "中级工程师")); 
 positions.put(4, new position(4, "初级工程师")); 
 positions.put(5, new position(5, "java实习生")); 
 } 
 
 // 模拟查询所有数据 
 public collection<position> queryallpositions(){ 
 return positions.values(); 
 } 
 
 // 模拟通过id查询数据 
 public position getpositionbyid(integer id){ 
 return positions.get(id); 
 } 
 
} 

用户列表页面的list.jsp

<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 
 
<!doctype html"> 
<html> 
<head> 
<meta http-equiv="content-type" content="text/html; charset=utf-8"> 
<title>springmvc 表单操作</title> 
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="stylesheet"> 
<script src="https://code.jquery.com/jquery.js"></script> 
<script type="text/javascript"> 
 $(function(){ 
 $(".delete").click(function(){ 
  var msg = confirm("确定要删除这条数据?"); 
  if (true == msg) { 
  $(this).onclick(); 
  } else { 
  return false; 
  } 
 }); 
 }) 
</script> 
</head> 
<body> 
 
 
 <!-- 用于删除的form --> 
 <form action="" method="post" id="deleteform"> 
 <input type="hidden" name="_method" value="delete"/> 
 </form> 
 
 <div class="container"> 
 <div class="row"> 
  <div class="col-sm-9"> 
  <c:if test="${empty requestscope.users }"> 
  没有任何员工信息. 
  </c:if> 
  <c:if test="${!empty requestscope.users }"> 
  <div class="table-responsive"> 
   <table class="table table-bordered"> 
   <caption>用户信息表 <a href="user" rel="external nofollow" class="btn btn-default" >add account</a></caption> 
   <thead> 
   <tr> 
    <th>用户编码</th> 
    <th>账号名</th> 
    <th>邮箱</th> 
    <th>性别</th> 
    <th>职位</th> 
    <th>薪水</th> 
    <th>时间</th> 
    <th>编辑</th> 
    <th>删除</th> 
   </tr> 
   </thead> 
   <tbody> 
   <c:foreach items="${requestscope.users }" var="user"> 
    <tr> 
    <td>${user.id }</td> 
    <td>${user.account }</td> 
    <td>${user.email }</td> 
    <td>${user.sex == 0 ? 'female' : 'male' }</td> 
    <td>${user.position.level }</td> 
    <td>${user.salary }</td> 
    <td><fmt:formatdate value="${user.createddate }" pattern="yyyy-mm-dd hh:mm:ss"/></td> 
    <td><a href="user/${user.id}" rel="external nofollow" >edit</a></td> 
    <td><a class="delete" href="delete/${user.id}" rel="external nofollow" >delete</a></td> 
    </tr> 
   </c:foreach> 
   </tbody> 
   </table> 
  </div> 
  </c:if> 
  </div> 
 </div> 
 </div> 
 
</body> 
</html> 

注意事项

javax.validation.unexpectedtypeexception: hv000030: no validator could be found for constraint '
使用hibernate validator出现上面的错误, 需要 注意
@notnull 和 @notempty 和@notblank 区别
@notempty 用在集合类上面
@notblank 用在string上面
@notnull 用在基本类型上

如果在基本类型上面用notempty或者notblank 会出现上面的错,笔者将@notempty用到了date上,导致出了这个问题。若还有问题,还继续在这里补充。

以上便是springmvc的表单操作,其中包含了常用知识,如数据的格式化,数据的校验,提示信息国际化,form标签的用法。