SpringMVC實(shí)現(xiàn)表單驗(yàn)證功能詳解
本章節(jié)內(nèi)容很豐富,主要有基本的表單操作,數(shù)據(jù)的格式化,數(shù)據(jù)的校驗(yàn),以及提示信息的國(guó)際化等實(shí)用技能。
首先看效果圖

項(xiàng)目結(jié)構(gòu)圖

接下來(lái)用代碼重點(diǎn)學(xué)習(xí)SpringMVC的表單操作,數(shù)據(jù)格式化,數(shù)據(jù)校驗(yàn)以及錯(cuò)誤提示信息國(guó)際化。請(qǐng)讀者將重點(diǎn)放在UserController.java,User.java,input.jsp三個(gè)文件中。
maven 項(xiàng)目必不可少的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>
<!-- 若不配置,打包時(shí)會(huì)提示錯(cuò)誤信息
Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project springmvc: Compilation failure:
提示 未結(jié)束的字符串文字 ,若字符串后面加上空格后可以打包成功,但會(huì)亂碼。
原因是:maven使用的是默認(rèn)的compile插件來(lái)進(jìn)行編譯的。complier是maven的核心插件之一,然而complier插件默認(rèn)只支持編譯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> <!-- 配置注解驅(qū)動(dòng) --> <mvc:annotation-driven /> <!-- 配置視圖 BeanNameViewResolver 解析器 使用視圖的名字來(lái)解析視圖 通過(guò) order 屬性來(lái)定義視圖解析器的優(yōu)先級(jí), order 值越小優(yōu)先級(jí)越高 --> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"> <property name="order" value="100"></property> </bean> <!-- 配置直接跳轉(zhuǎn)的頁(yè)面,無(wú)需經(jīng)過(guò)Controller層 http://localhost:8080/springmvc/index 然后會(huì)跳轉(zhuǎn)到 WEB-INF/views/index.jsp 頁(yè)面 --> <mvc:view-controller path="/index" view-name="index"/> <mvc:default-servlet-handler/> <!-- 配置國(guó)際化資源文件 --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="i18n"></property> </bean> </beans>
以上是準(zhǔn)備工作。下面開(kāi)始核心代碼介紹。
數(shù)據(jù)的校驗(yàn)思路:
第一步,在實(shí)體類(lèi)中指定屬性添加校驗(yàn)注解(如@NotEmpty),
第二步,在控制層目標(biāo)方法實(shí)體類(lèi)參數(shù)添加注解@Valid,
第三步,在返回頁(yè)面加上顯示提示錯(cuò)誤信息
數(shù)據(jù)格式化思路:只需要在實(shí)體類(lèi)中加上注解即可。
信息國(guó)際化思路:
第一步,在SpringMVC配置文件中配置國(guó)際化資源文件
第二步,創(chuàng)建文件i18n_zh_CN.properties文件
第三步,在i18n_zh_CN.properties文件配置國(guó)際化信息(要嚴(yán)格按照SpringMVC的語(yǔ)法)
UserController.java,兩個(gè)重點(diǎn)知識(shí)。一個(gè)是SpringMVC的rest風(fēng)格的增刪改查。另一個(gè)是@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"; // 跳轉(zhuǎn)到編輯頁(yè)面
private static final String LIST = "list"; // 跳轉(zhuǎn)到用戶(hù)列表頁(yè)面
@ModelAttribute
public void getUser(@RequestParam(value="id",required=false) Integer id,
Map<String, Object> map){
if(id != null){
map.put("user", userDao.getUserById(id));
}
}
// 更新用戶(hù),用put請(qǐng)求方式區(qū)別get請(qǐng)求方式,屬于SpringMVC rest 風(fēng)格的crud
@RequestMapping(value="/user", method=RequestMethod.PUT)
public String updateUser(User user){
userDao.save(user);
return "redirect:/users";
}
// 點(diǎn)擊編輯跳轉(zhuǎn)編輯頁(yè)面
@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;
}
// 通過(guò)id刪除用戶(hù)
@RequestMapping(value="/delete/{id}", method=RequestMethod.GET)
public String delete(@PathVariable("id") Integer id){
userDao.deleteUserById(id);
return "redirect:/users";
}
/**
* 新增用戶(hù),若保存成功則跳轉(zhuǎn)到用戶(hù)列表頁(yè)面,若失敗則跳轉(zhuǎn)到編輯頁(yè)面
* @param user 用 @Valid 注解修飾后,可實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)的邏輯
* @param result 數(shù)據(jù)校驗(yàn)結(jié)果
* @param map 數(shù)據(jù)模型
* @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;
}
// 跳轉(zhuǎn)用戶(hù)列表頁(yè)面
@RequestMapping("/users")
public String list(Map<String, Object> map){
map.put("users", userDao.queryAllUsers());
return LIST;
}
}
User.java,兩個(gè)重點(diǎn)知識(shí)。一個(gè)是數(shù)據(jù)的格式化(包括日期格式化和數(shù)值格式化)。另一個(gè)是使用 JSR 303 驗(yàn)證標(biāo)準(zhǔn)數(shù)據(jù)校驗(yàn)。
數(shù)據(jù)格式化,由于前端傳給后臺(tái)的是字符串,對(duì)于比較特殊的屬性,比如Date,F(xiàn)loat類(lèi)型就需要進(jìn)行數(shù)據(jù)格式化
** @NumberFormat 數(shù)值格式化 **
可以格式化/解析的數(shù)字類(lèi)型:Short、Integer、Long、Float、Double、BigDecimal、BigInteger。
屬性參數(shù)有:pattern="###,###.##"(重點(diǎn))。
style= org.springframework.format.annotation.NumberFormat.Style.NUMBER(CURRENCY / PERCENT)。其中Style.NUMBER(通用樣式,默認(rèn)值);Style.CURRENCY(貨幣樣式);Style.PERCENT(百分?jǐn)?shù)樣式)
** @DateTimeFormat 日期格式化 **
可以格式化/解析的數(shù)字類(lèi)型:java.util.Date 、java.util.Calendar 、java.long.Long。
屬性參數(shù)有:pattern="yyyy-MM-dd hh:mm:ss"(重點(diǎn))。
iso=指定解析/格式化字段數(shù)據(jù)的ISO模式,包括四種:ISO.NONE(不使用ISO模式,默認(rèn)值),ISO.DATE(yyyy-MM-dd),ISO.TIME(hh:mm:ss.SSSZ),ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ);style=指定用于格式化的樣式模式,默認(rèn)“SS”,優(yōu)先級(jí): pattern 大于 iso 大于 style,后兩個(gè)很少用。
數(shù)據(jù)校驗(yàn)
空檢查
** @Null ** 驗(yàn)證對(duì)象是否為null
** @NotNull ** 驗(yàn)證對(duì)象是否不為null, 無(wú)法查檢長(zhǎng)度為0的字符串
** @NotBlank ** 檢查約束字符串是不是Null還有被Trim的長(zhǎng)度是否大于0,只對(duì)字符串,
且會(huì)去掉前后空格
** @NotEmpty ** 檢查約束元素是否為NULL或者是EMPTY
Booelan檢查
** @AssertTrue ** 驗(yàn)證 Boolean 對(duì)象是否為 true
** @AssertFalse ** 驗(yàn)證 Boolean 對(duì)象是否為 false
長(zhǎng)度檢查
** @Size(min=, max=) ** 驗(yàn)證對(duì)象(Array,Collection,Map,String)值是否在給定的范圍之內(nèi)
** @Length(min=, max=) ** 驗(yàn)證對(duì)象(CharSequence子類(lèi)型)長(zhǎng)度是否在給定的范圍之內(nèi)
日期檢查
** @Past ** 驗(yàn)證 Date 和 Calendar 對(duì)象是否在當(dāng)前時(shí)間之前
** @Future ** 驗(yàn)證 Date 和 Calendar 對(duì)象是否在當(dāng)前時(shí)間之后
** @Pattern ** 驗(yàn)證 String 對(duì)象是否符合正則表達(dá)式的規(guī)則
數(shù)值檢查
** @Min ** 驗(yàn)證 Number 和 String 對(duì)象是否大等于指定的值
** @Max ** 驗(yàn)證 Number 和 String 對(duì)象是否小等于指定的值
** @DecimalMax ** 被標(biāo)注的值必須不大于約束中指定的最大值. 這個(gè)約束的參數(shù)
是一個(gè)通過(guò)BigDecimal定義的最大值的字符串表示.小數(shù)存在精度
** @DecimalMin ** 被標(biāo)注的值必須不小于約束中指定的最小值. 這個(gè)約束的參數(shù)
是一個(gè)通過(guò)BigDecimal定義的最小值的字符串表示.小數(shù)存在精度
** @Digits ** 驗(yàn)證 Number 和 String 的構(gòu)成是否合法
** @Digits(integer=,fraction=) ** 驗(yàn)證字符串是否是符合指定格式的數(shù)字,interger指定整數(shù)精度,fraction指定小數(shù)精度
** @Range(min=, max=) ** 檢查數(shù)字是否介于min和max之間
** @CreditCardNumber ** 信用卡驗(yàn)證
** @Email ** 驗(yàn)證是否是郵件地址,如果為null,不進(jìn)行驗(yàn)證,算通過(guò)驗(yàn)證
** @ScriptAssert(lang= ,script=, alias=) ** 通過(guò)腳本驗(yàn)證
其中有幾點(diǎn)需要注意:
空判斷注解
String name @NotNull @NotEmpty @NotBlank null false false false "" true false false " " true true false "ITDragon!" true true true
數(shù)值檢查:建議使用在Stirng,Integer類(lèi)型,不建議使用在int類(lèi)型上,因?yàn)楸韱沃禐椤啊睍r(shí)無(wú)法轉(zhuǎn)換為int,但可以轉(zhuǎn)換為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 表單標(biāo)簽知識(shí)點(diǎn)詳解
<%@ 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 rel="external nofollow" rel="external nofollow" rel="stylesheet">
</head>
<body>
<!--
1. 使用 form 標(biāo)簽可以更快速的開(kāi)發(fā)出表單頁(yè)面, 而且可以更方便的進(jìn)行表單值的回顯。
step1 導(dǎo)入標(biāo)簽 taglib prefix="form" uri="http://www.springframework.org/tags/form"
step2 和普通的form用法差不多。path 相當(dāng)于 普通的form的name,form:hidden 隱藏域,form:errors 提示錯(cuò)誤信息。
2. 使用form 標(biāo)簽需要注意:
通過(guò) modelAttribute 屬性指定綁定的模型屬性, 該數(shù)據(jù)模型必須是實(shí)例化過(guò)的。
若沒(méi)有 modelAttribute 指定該屬性,則默認(rèn)從 request 域?qū)ο笾凶x取 command 的表單 bean (如果該屬性值也不存在,則會(huì)發(fā)生錯(cuò)誤)。
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">修改或創(chuàng)建用戶(hù)信息</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 屬性對(duì)應(yīng) html 表單標(biāo)簽的 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"/>
<%-- 對(duì)于 _method 不能使用 form:hidden 標(biāo)簽, 因?yàn)?modelAttribute 對(duì)應(yīng)的 bean 中沒(méi)有 _method 這個(gè)屬性 --%>
<%--
<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國(guó)際化文件
#語(yǔ)法:實(shí)體類(lèi)上屬性的注解.驗(yàn)證目標(biāo)方法的modleAttribute 屬性值(如果沒(méi)有默認(rèn)為實(shí)體類(lèi)首字母小寫(xiě)).注解修飾的屬性
#以第一個(gè)為例:User實(shí)體類(lèi)中 屬性account用了NotEmpty注解修飾,表示不能為空。所以前綴是NotEmpty
#驗(yàn)證的目標(biāo)方法 public String save(@Valid User user, ...) User被注解@Valid 修飾,但沒(méi)有被modleAttribute修飾。所以中間是user
#后綴就是被注解修飾的屬性名 account
NotEmpty.user.account=用戶(hù)名不能為空
Email.user.email=Email地址不合法
#typeMismatch 數(shù)據(jù)類(lèi)型不匹配時(shí)提示
typeMismatch.user.createdDate=不是一個(gè)日期
#required 必要參數(shù)不存在時(shí)提示
#methodInvocation 調(diào)用目標(biāo)方法出錯(cuò)的時(shí)提示
其他文件,Position 實(shí)體類(lèi)
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 + "]";
}
}
模擬用戶(hù)操作的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;
// 模擬數(shù)據(jù)庫(kù)查詢(xún)數(shù)據(jù)
static{
users = new HashMap<Integer, User>();
users.put(1, new User(1, "ITDragon", "11@xl.com", 1, new Position(1, "架構(gòu)師"), new Date(), 18888.88));
users.put(2, new User(2, "Blog", "22@xl.com", 1, new Position(2, "高級(jí)工程師"), new Date(), 15555.55));
users.put(3, new User(3, "Welcome", "33@xl.com", 0, new Position(3, "中級(jí)工程師"), new Date(), 8888.88));
users.put(4, new User(4, "To", "44@xl.com", 0, new Position(4, "初級(jí)工程師"), new Date(), 5555.55));
users.put(5, new User(5, "You", "55@xl.com", 1, new Position(5, "java實(shí)習(xí)生"), new Date(), 2222.22));
}
// 下一次存儲(chǔ)的下標(biāo)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, "架構(gòu)師"));
positions.put(2, new Position(2, "高級(jí)工程師"));
positions.put(3, new Position(3, "中級(jí)工程師"));
positions.put(4, new Position(4, "初級(jí)工程師"));
positions.put(5, new Position(5, "java實(shí)習(xí)生"));
}
// 模擬查詢(xún)所有數(shù)據(jù)
public Collection<Position> queryAllPositions(){
return positions.values();
}
// 模擬通過(guò)id查詢(xún)數(shù)據(jù)
public Position getPositionById(Integer id){
return positions.get(id);
}
}
用戶(hù)列表頁(yè)面的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 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("確定要?jiǎng)h除這條數(shù)據(jù)?");
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 }">
沒(méi)有任何員工信息.
</c:if>
<c:if test="${!empty requestScope.users }">
<div class="table-responsive">
<table class="table table-bordered">
<caption>用戶(hù)信息表 <a href="user" rel="external nofollow" class="btn btn-default" >Add Account</a></caption>
<thead>
<tr>
<th>用戶(hù)編碼</th>
<th>賬號(hào)名</th>
<th>郵箱</th>
<th>性別</th>
<th>職位</th>
<th>薪水</th>
<th>時(shí)間</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>
注意事項(xiàng)
javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint '
使用hibernate validator出現(xiàn)上面的錯(cuò)誤, 需要 注意
@NotNull 和 @NotEmpty 和@NotBlank 區(qū)別
@NotEmpty 用在集合類(lèi)上面
@NotBlank 用在String上面
@NotNull 用在基本類(lèi)型上
如果在基本類(lèi)型上面用NotEmpty或者NotBlank 會(huì)出現(xiàn)上面的錯(cuò),筆者將@NotEmpty用到了Date上,導(dǎo)致出了這個(gè)問(wèn)題。若還有問(wèn)題,還繼續(xù)在這里補(bǔ)充。
以上便是SpringMVC的表單操作,其中包含了常用知識(shí),如數(shù)據(jù)的格式化,數(shù)據(jù)的校驗(yàn),提示信息國(guó)際化,F(xiàn)orm標(biāo)簽的用法。
- layui 圖片上傳+表單提交+ Spring MVC的實(shí)例
- springMVC中基于token防止表單重復(fù)提交方法
- SpringMVC中使用bean來(lái)接收f(shuō)orm表單提交的參數(shù)時(shí)的注意點(diǎn)
- SpringMVC實(shí)現(xiàn)數(shù)據(jù)綁定及表單標(biāo)簽
- Spring MVC---數(shù)據(jù)綁定和表單標(biāo)簽詳解
- [Spring MVC] -簡(jiǎn)單表單提交實(shí)例
- SpringMVC處理Form表單實(shí)例
- Spring MVC中基于自定義Editor的表單數(shù)據(jù)處理技巧分享
- SpringMVC表單提交參數(shù)400錯(cuò)誤解決方案
相關(guān)文章
Java調(diào)用ChatGPT的實(shí)現(xiàn)代碼
這篇文章主要介紹了Java調(diào)用ChatGPT的實(shí)現(xiàn)代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02
Post請(qǐng)求參數(shù)是數(shù)組或者List時(shí)的請(qǐng)求處理方式
這篇文章主要介紹了Post請(qǐng)求參數(shù)是數(shù)組或者List時(shí)的請(qǐng)求處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
springboot maven 項(xiàng)目打包jar 最后名稱(chēng)自定義的教程
這篇文章主要介紹了springboot maven 項(xiàng)目打包jar 最后名稱(chēng)自定義的教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
MyBatis學(xué)習(xí)教程之開(kāi)發(fā)Dao的方法教程
這篇文章主要給大家介紹了關(guān)于MyBatis開(kāi)發(fā)Dao的相關(guān)資料,使用Mybatis開(kāi)發(fā)Dao,通常有兩個(gè)方法,即原始Dao開(kāi)發(fā)方法和Mapper接口開(kāi)發(fā)方法。文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面來(lái)一起看看吧。2017-07-07
Java設(shè)計(jì)模式中的策略模式詳細(xì)解析
這篇文章主要介紹了Java設(shè)計(jì)模式中的策略模式詳細(xì)解析,所謂策略模式,指的是做某一件事時(shí)有多種選擇(即策略),且不同的策略之間相互獨(dú)立,而且無(wú)論使用哪種策略,得到的結(jié)果都是相同的,需要的朋友可以參考下2023-12-12
Java實(shí)現(xiàn)中序表達(dá)式的實(shí)例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)中序表達(dá)式的實(shí)例代碼,需要的朋友可以參考下2018-08-08

