栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringMVC实现表单验证功能详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringMVC实现表单验证功能详解

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

项目结构图

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

 
 
 4.0.0 
 com.springmvc 
 springmvc 
 0.0.1-SNAPSHOT 
 war 
 
  
  
  
   
   maven-compiler-plugin 
    
    1.7 
    1.7 
    UTF-8 
    
   
  
  
 
  
 4.1.3.RELEASE 
  
  
  
  
  org.springframework 
  spring-webmvc 
  ${spring.version} 
  
 
  
  org.springframework 
  spring-context 
  ${spring.version} 
  
 
  
  org.springframework 
  spring-aop 
  ${spring.version} 
  
 
  
  org.springframework 
  spring-core 
  ${spring.version} 
  
  
  
  org.springframework 
  spring-web 
  ${spring.version} 
  
 
  
  
  javax.servlet 
  javax.servlet-api 
  4.0.0 
  provided 
  
  
  javax.servlet 
  jstl 
  1.2 
  
  
  taglibs 
  standard 
  1.1.2 
  
  
  
  javax.servlet.jsp 
  jsp-api 
  2.2 
  provided 
  
  
  
  org.hibernate 
  hibernate-validator 
  5.4.1.Final 
  
  
  javax.validation 
  validation-api 
  1.1.0.Final 
  
  
   
  
 

SpringMVC的核心配置文件

 
 
 
  
  
 
  
  
   
   
  
  
  
  
 
  
  
   
  
  
  
  
  
  
  
  
  
   
  
  
 

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

数据的校验思路:

第一步,在实体类中指定属性添加校验注解(如@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 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 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"; 
 } 
  
  
 @RequestMapping(value="/user", method=RequestMethod.POST) 
 public String save(@Valid User user, Errors result, Map 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 map){ 
  map.put("positions", positionDao.queryAllPositions()); 
  map.put("user", new User()); 
  return INPUT; 
 } 
  
 // 跳转用户列表页面 
 @RequestMapping("/users") 
 public String list(Map 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
nullfalse    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" %> 
 
 
 
 
 
SpringMVC 表单操作 
 
 
 
 
  
  
  
   
   
   
   

修改或创建用户信息 没有任何员工信息.
用户信息表 Add Account
用户编码 账号名 邮箱 性别 职位 薪水 时间 编辑 删除
${user.id } ${user.account } ${user.email } ${user.sex == 0 ? 'Female' : 'Male' } ${user.position.level } ${user.salary } Edit Delete

注意事项

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标签的用法。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/143553.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号