Spring MVC 数据验证
本小记学习目标
-
对数据验证的了解
-
Spring自带验证框架学习
-
JSR 303验证学习
一、数据验证的了解
数据验证分为客户端验证和服务端验证。
客户端验证:主要是防止用户的误操作而提交错误数据,一般使用JavaScript完成
验证的通常步骤:(JavaScript)
1.编写验证函数
2.在提交表单的事件中调用验证函数
3.根据验证函数来判断是否进行表单数据的提交
服务端验证:服务端验证是对客户端提交的数据做非法验证,它是验证的最后防线,一 般是在应用中编程来实现
Spring MVC的Converter和Formatter在进行类型转换时把输入数据转换成领域对象的属性值,当成功后,服务端验证器则会介入工作,在Spring MVC框架中可以利用Spring自带的验证框架验证数据,也可以利用JSR 303实现数据验证
二、Spring自带验证框架
Validator接口
org.springframework.validation.Validator接口,在创建自定义Spring验证器时需要实现这个接口
这个接口有两个接口方法:
boolean supports(Class<?> clazz)
void validate(Object target,Errors errors)
当supports方法返回true时,验证器可以处理指定Class。validate方法的功能是验证目标对象target,并把验证的错误消息存入Errors对象
向Errors对象存入错误消息的方法是reject或rejectValue,这两个方法的部分重载方法如下
void reject(String errorCode)
void reject(String errorCode,String defaultMessage)
void rejectValue(String field,String errorCode)
void rejectValue(String field,String errorCode,String defaultMessage)
一般来说要给reject或rejectValue方法一个错误代码,Spring MVC框架会在消息属性文件中查找错误代码,获取对应的错误消息
ValidationUtils类
org.springframework.validation.validationUtil是一个验证工具类
在这个类中有一些方法可以进行空值判断
ValidationUtils.rejectIfEmpty()
ValidationUtils.rejectIfEmptyOrWhitespace()
Spring自带验证框架实例
1.新增一个maven的war工程,在pom.xml中添加如下依赖
<
dependencies
>
<!-- context -->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-context
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<!-- Spring MVC -->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-
webmvc
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<!-- Spring web -->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-web
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<!-- commons-logging -->
<
dependency
>
<
groupId
>commons-logging
</
groupId
>
<
artifactId
>commons-logging
</
artifactId
>
<
version
>1.2
</
version
>
</
dependency
>
<!-- spring-
aop
-->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-
aop
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<
dependency
>
<
groupId
>javax.servlet
</
groupId
>
<
artifactId
>
jstl
</
artifactId
>
<
version
>1.2
</
version
>
</
dependency
>
</
dependencies
>
2.新增一个实体类Goods:com.xiaoxie.pojo.Goods
package com.xiaoxie.pojo;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
/*实体类:Goods*/
public
class Goods {
private String
gcode;
//商品编码
private String
gname;
//商品名称
private
double
gprice;
//商品售卖价格
//日期格式化
@DateTimeFormat(pattern=
"yyyy-MM-dd")
private Date
gdate;
//生产日期
public String getGcode() {
return
gcode;
}
public
void setGcode(String
gcode) {
this.
gcode =
gcode;
}
public String getGname() {
return
gname;
}
public
void setGname(String
gname) {
this.
gname =
gname;
}
public Date getGdate() {
return
gdate;
}
public
double getGprice() {
return
gprice;
}
public
void setGprice(
double
gprice) {
this.
gprice =
gprice;
}
public
void setGdate(Date
gdate) {
this.
gdate =
gdate;
}
@Override
public String toString() {
return
"Goods:[gcode= " + getGcode() +
",gname= " + getGname() +
",gdate= " + getGdate() +
"]";
}
}
3.配置前端核心控制器springDispatcherServlet(web.xml)
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<
web-app
xmlns:xsi=
"
http://www.w3.org/2001/XMLSchema-instance
"
xmlns=
"
http://java.sun.com/xml/ns/javaee
"
xsi:schemaLocation=
"
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
"
id=
"WebApp_ID"
version=
"2.5"
>
<!-- 前端核心
servlet
的配置(DispatcherServlet) -->
<
servlet
>
<
servlet-name
>springDispatcherServlet
</
servlet-name
>
<
servlet-class
>org.springframework.web.servlet.DispatcherServlet
</
servlet-class
>
<
init-param
>
<
param-name
>contextConfigLocation
</
param-name
>
<
param-value
>classpath:springmvc.xml
</
param-value
>
</
init-param
>
<
load-on-startup
>1
</
load-on-startup
>
</
servlet
>
<!-- Map all requests to the DispatcherServlet for handling -->
<
servlet-mapping
>
<
servlet-name
>springDispatcherServlet
</
servlet-name
>
<
url-pattern
>/
</
url-pattern
>
</
servlet-mapping
>
<!-- 配置解决
psot
请求中文乱码问题 -->
<
filter
>
<
filter-name
>CharacterEncodingFilter
</
filter-name
>
<
filter-class
>org.springframework.web.filter.CharacterEncodingFilter
</
filter-class
>
<
init-param
>
<
param-name
>encoding
</
param-name
>
<
param-value
>
utf-8
</
param-value
>
</
init-param
>
<
init-param
>
<
param-name
>forceEncoding
</
param-name
>
<
param-value
>true
</
param-value
>
</
init-param
>
</
filter
>
<
filter-mapping
>
<
filter-name
>CharacterEncodingFilter
</
filter-name
>
<
url-pattern
>/*
</
url-pattern
>
</
filter-mapping
>
</
web-app
>
4.在/WEB-INF/jsp的目录下新增addGoods.jsp(这个页面用来添加商品信息)
<%@
page
language=
"java"
contentType=
"text/html; charset=UTF-8"
pageEncoding=
"UTF-8"
%>
<!
DOCTYPE
html
PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"
http://www.w3.org/TR/html4/loose.dtd
"
>
<
html
>
<
head
>
<
meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<
title
>添加商品
</
title
>
</
head
>
<
body
>
<
form:form
modelAttribute=
"goods"
action=
"${pageContext.request.contextPath }
/goods/save"
method=
"post"
>
<
fieldset
>
<
legend
>添加商品
</
legend
>
<
p
>
<
label
>商品编码:
</
label
>
<
form:input
path=
"gcode"
/>
</
p
>
<
p
>
<
label
>商品名称:
</
label
>
<
form:input
path=
"gname"
/>
</
p
>
<
p
>
<
label
>商品售价:
</
label
>
<
form:input
path=
"gprice"
/>
</
p
>
<
p
>
<
label
>生产日期:
</
label
>
<
form:input
path=
"gdate"
/>(yyyy-MM-dd)
</
p
>
<
p
id=
"btn"
>
<
input
id=
"reset"
type=
"reset"
>
<
input
id=
"submit"
type=
"submit"
value=
"添加"
>
</
p
>
<!-- 验证错误信息 -->
<
form:errors
path=
"*"
/>
</
fieldset
>
</
form:form
>
</
body
>
</
html
>
5.编写验证器类:com.xiaoxie.validator.GoodsValidation(实现Validator接口)
package com.xiaoxie.validator;
import java.util.Date;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.xiaoxie.pojo.Goods;
@Component
public
class GoodsValidation
implements Validator{
@
Override
public
boolean supports(Class<?>
clazz) {
//需要验证的model,返回false则不需要验证
return Goods.
class.isAssignableFrom(
clazz);
}
@
Override
public
void validate(Object
target, Errors
errors) {
Goods
goods = (Goods)
target;
//target为需要验证的对象
ValidationUtils.
rejectIfEmpty(
errors,
"gcode",
"goods.gcode.required");
ValidationUtils.
rejectIfEmpty(
errors,
"gname",
"goods.gname.required");
//商品的售卖价格不允许小于0
if(
goods.getGprice()<0) {
errors.rejectValue(
"gprice",
"gprice.invalid");
}
Date
goodsDate =
goods.getGdate();
if(
goodsDate ==
null) {
errors.rejectValue(
"gdate",
"gdate.invalid");
}
if(
goodsDate !=
null &&
goodsDate.after(
new Date())) {
errors.rejectValue(
"gdate",
"gdate.invalid");
}
}
}
6.编写错误消息属性文件,messages.properties(在src/main/resources下),注意这个文件使用utf-8编码格式
goods.gcode.required=
请输入商品编码
goods.gname.required=
请输入商品名称
gprice.invalid=
商品售卖价格不允许小于0
gdate.invalid=
商品生产日期不可以为空且不可以在系统日期之后
7.编写Service层包含:GoodsService接口和它的实现类GoodsServiceImpl
GoodsService接口:
package com.xiaoxie.service;
import java.util.ArrayList;
import com.xiaoxie.pojo.Goods;
public
interface GoodsService {
boolean save(Goods
g);
ArrayList<Goods> getGoods();
}
GoodsServiceImpl实现类:
package com.xiaoxie.service.impl;
import java.util.ArrayList;
import org.springframework.stereotype.Service;
import com.xiaoxie.pojo.Goods;
import com.xiaoxie.service.GoodsService;
@
Service
public
class GoodsServiceImpl
implements GoodsService {
//这里使用一个静态集合变量模拟数据库
private
static ArrayList<Goods>
goods =
new ArrayList<>();
@Override
public
boolean save(Goods
g) {
goods.add(
g);
//向集合中添加商品
return
true;
}
@Override
public ArrayList<Goods> getGoods() {
return
goods;
//返回集合
}
}
8.编写Controller类:GoodsController
package com.xiaoxie.controller;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.xiaoxie.pojo.Goods;
import com.xiaoxie.service.GoodsService;
@Controller
@RequestMapping(
"/goods")
public
class GoodsController {
//日志记录
private
static
final Log
logger = LogFactory.
getLog(GoodsController.
class);
@Autowired
private GoodsService
goodsService;
@Resource
//这里相关于 GoodsValidator
validator
= new GoodsValidation();
private Validator
validator;
@RequestMapping(
"/input")
public String input(Model
model) {
model.addAttribute(
"goods",
new Goods());
return
"addGoods";
}
@RequestMapping(
"/save")
public String save(
@ModelAttribute Goods
goods,BindingResult
result,Model
model) {
this.
validator.validate(
goods,
result);
//验证
if(
result.hasErrors()) {
return
"addGoods";
}
goodsService.save(
goods);
logger.info(
"商品添加成功!");
model.addAttribute(
"goodsList",
goodsService.getGoods());
return
"goodsList";
}
}
9.新增Spring MVC配置文件(src/main/resources下)springmvc.xml(这个名称与web.xml中指定的配置文件名称要一致)
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
xsi:schemaLocation=
"
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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.3.xsd
"
>
<!-- spring自动扫描 -->
<
context:component-scan
base-package=
"com.xiaoxie.controller"
/>
<
context:component-scan
base-package=
"com.xiaoxie.service"
/>
<
context:component-scan
base-package=
"com.xiaoxie.validator"
/>
<!-- 注册格式化转换器,在项目中使用到了日期格式化转换 -->
<
bean
class=
"org.springframework.format.support.FormattingConversionServiceFactoryBean"
id=
"formattingConversionServiceFactoryBean"
>
</
bean
>
<
mvc:annotation-driven
conversion-service=
"formattingConversionServiceFactoryBean"
/>
<!-- 加载国际化资源文件 -->
<
bean
id=
"messageSource"
class=
"org.springframework.context.support.ResourceBundleMessageSource"
>
<
property
name=
"
basenames"
value=
"messages"
/>
<!-- 防止出现中文乱码的情况,指定使用UTF-8编码 -->
<
property
name=
"
defaultEncoding"
value=
"UTF-8"
/>
</
bean
>
<
mvc:interceptors
>
<!-- 国际化操作拦截器如果采用基于(Session/Cookie则必须配置) -->
<
bean
class=
"org.springframework.web.servlet.i18n.LocaleChangeInterceptor"
/>
</
mvc:interceptors
>
<
bean
id=
"localeResolver"
class=
"org.springframework.web.servlet.i18n.SessionLocaleResolver"
/>
<!-- 配置视图解析器 -->
<
bean
class=
"org.springframework.web.servlet.view.InternalResourceViewResolver"
id=
"internalResourceViewResolver"
>
<!-- 前缀 -->
<
property
name=
"
prefix"
value=
"/WEB-INF/jsp/"
/>
<!-- 后缀 -->
<
property
name=
"
suffix"
value=
".jsp"
/>
</
bean
>
</
beans
>
10.新增goodsList.jsp用来展示商品信息(/WEB-INF/jsp下)
<%@
page
language=
"java"
contentType=
"text/html; charset=UTF-8"
pageEncoding=
"UTF-8"
%>
<!
DOCTYPE
html
PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"
http://www.w3.org/TR/html4/loose.dtd
"
>
<
html
>
<
head
>
<
meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<
title
>商品列表
</
title
>
</
head
>
<
body
>
<
table
border=
"1"
cellspacing=
"0"
>
<
tr
>
<
td
>商品编码
</
td
>
<
td
>商品名称
</
td
>
<
td
>商吕价格
</
td
>
<
td
>生产日期
</
td
>
</
tr
>
<
c:forEach
items=
"${goodsList }
"
var=
"goods"
>
<
tr
>
<
td
>${goods.gcode }
</
td
>
<
td
>${goods.gname }
</
td
>
<
td
>${goods.gprice }
</
td
>
<!-- 对日期进行格式化展示 -->
<
td
><
fmt:formatDate
value=
"${goods.gdate }
"
pattern=
"yyyy-MM-dd"
/></
td
>
</
tr
>
</
c:forEach
>
</
table
>
</
body
>
</
html
>
完成上面的工程配置后,运行工程则可以看到在不满足验证的条件时会转发到addGoods.jsp页面同时错误的提示信息也会在页面展示
三、JSR 303验证
JSR 303验证,有两个实现:Hibernate Validator;Apache BVal
Hibernate Validator它使用了Hibernate进行数据验证
JSR 303验证不需要编写验证器,但是需要利用它的标注类型在领域模型的属性上嵌入约束。
标注类型说明
标注组
|
标注
|
说明
|
空校验
|
@Null
|
验证对像是否为null
|
@NotNull
|
验证对象是否不为null,无法校验长度为0的字符串
| |
@NotBlank
|
验证约束字符串是否为null及被trim后的长度是否大于0,只针对字符串并且会去掉前后的空格
| |
boolean校验 |
@AssertTrue
|
验证boolean属性是否为true
|
@AssertFalse
|
验证boolean属性是否为false
| |
长度校验
|
@Size(min=,max=)
|
验证对象(Array,Collection,Map,String)长度是否在给定范围内
|
@Length(min=,max=)
|
验证字符串的长度是否在给定的范围内
| |
日期校验
|
@Past
|
验证Date和Calendar对象是否在当前时间之前
|
@Future
|
验证Date和Calendar对象是否在当前时间之后
| |
@Pattern
|
验证String对象是否符合正则表达式的规则
| |
数值校验
|
@Min
|
验证Number和String对象是否大于指定的值
|
@Max
|
验证Number和String对象是否小于指定的值
| |
@DecimalMax
|
被标注的值必须不大于约束指定的最大值
| |
@DecimalMin
|
被标注的值必须不小于约束中指定的最小值
| |
@Digits
|
验证Number和String的构成是否合法
| |
@Digits(interger=,fraction=)
|
验证字符串是否符合指定格式的数字,Interger表示整理数精度,fraction表示小数的精度
| |
@Range(min=,max=)
|
检查数字是否介于min和max之间
| |
@Valid
|
对关联对象进行校验,如果关联对象是个集合或数组,那么对其中元素进行校验,如果是一个map,则对其中的值部值部分进行校验
| |
@CreditCardNumber
|
信用卡验证
| |
@Email
|
验证是否为邮箱地址,如果为null则不进行验证(验证通过)
|
关于JSR 303验证实例
1.新增一个maven的war工程
2.在pom.xml中新增如下依赖
<
dependencies
>
<!-- context -->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-context
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<!-- Spring MVC -->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-
webmvc
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<!-- Spring web -->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-web
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<!-- commons-logging -->
<
dependency
>
<
groupId
>commons-logging
</
groupId
>
<
artifactId
>commons-logging
</
artifactId
>
<
version
>1.2
</
version
>
</
dependency
>
<!-- spring-
aop
-->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-
aop
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<
dependency
>
<
groupId
>javax.servlet
</
groupId
>
<
artifactId
>
jstl
</
artifactId
>
<
version
>1.2
</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.hibernate.validator
</
groupId
>
<
artifactId
>
hibernate-
validator
</
artifactId
>
<
version
>6.1.5.Final
</
version
>
</
dependency
>
</
dependencies
>
3.新增一个领域模型的实体对象com.xiaoxie.pojo.Goods
package com.xiaoxie.pojo;
import java.util.Date;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Past;
import org.springframework.format.annotation.DateTimeFormat;
//领域对象:实体
public
class Goods {
@NotBlank(message=
"{goods.gcode.required}")
private String
gcode;
//商品编码
@NotBlank(message=
"{goods.gname.required}")
private String
gname;
//商品名称
@DecimalMin(value=
"0.0",message=
"{gprice.invalid}")
private
double
gprice;
//商品售卖价格
@DateTimeFormat(pattern=
"yyyy-MM-dd")
@Past(message=
"{gdate.invalid}")
private Date
gdate;
public String getGcode() {
return
gcode;
}
public
void setGcode(String
gcode) {
this.
gcode =
gcode;
}
public String getGname() {
return
gname;
}
public
void setGname(String
gname) {
this.
gname =
gname;
}
public
double getGprice() {
return
gprice;
}
public
void setGprice(
double
gprice) {
this.
gprice =
gprice;
}
public Date getGdate() {
return
gdate;
}
public
void setGdate(Date
gdate) {
this.
gdate =
gdate;
}
}
注意:在这个实体对象中使用标注的方式指定了校验的方式
4.新增一个service的接口及实现类
GoodsService接口:
package com.xiaoxie.service;
import java.util.ArrayList;
import com.xiaoxie.pojo.Goods;
public
interface GoodsService {
boolean save(Goods
g);
ArrayList<Goods> getGoods();
}
GoodsServiceImpl实现类:
package com.xiaoxie.service.impl;
import java.util.ArrayList;
import org.springframework.stereotype.Service;
import com.xiaoxie.pojo.Goods;
import com.xiaoxie.service.GoodsService;
@Service
public
class GoodsServiceImpl
implements GoodsService {
//这里使用一个静态集合变量模拟数据库
private
static ArrayList<Goods>
goods =
new ArrayList<>();
@Override
public
boolean save(Goods
g) {
goods.add(
g);
//向集合中添加商品
return
true;
}
@Override
public ArrayList<Goods> getGoods() {
return
goods;
//返回集合
}
}
5.新增controller的实现类:con.xiaoxie.controller.GoodsController
package com.xiaoxie.controller;
import
javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.xiaoxie.pojo.Goods;
import com.xiaoxie.service.GoodsService;
@Controller
@RequestMapping(
"/goods")
public
class GoodsController {
//logger
private
static
final Log
logger = LogFactory.
getLog(GoodsController.
class);
@Autowired
private GoodsService
goodsService;
@RequestMapping(
"/input")
public String input(Model
model) {
model.addAttribute(
"goods",
new Goods());
return
"addGoods";
}
@RequestMapping(
"/save")
public String save(
@
Validated
@ModelAttribute Goods
goods,BindingResult
result,Model
model) {
if(
result.hasErrors()) {
return
"addGoods";
}
goodsService.save(
goods);
logger.info(
"商品添加成功!");
model.addAttribute(
"goodsList",
goodsService.getGoods());
return
"goodsList";
}
}
注意:这里使用了@Validated注解而不是像Spring自带的验证框架一样新增验证的实现类,引入实现类后做验证
6.新增消息配置文件messages.properties(在classpath下[src/main/resources])
goods.gcode.required=
请输入商品编码
goods.gname.required=
请输入商品名称
gprice.invalid=
商品售卖价格不允许小于0
gdate.invalid=
商品生产日期不可以为空且不可以在系统日期之后
7.配置Spring的配置文件:springmvc.xml(在classpath下[src/main/resources])
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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.3.xsd"
>
<!-- 自动扫描包 -->
<
context:component-scan
base-package=
"com.xiaoxie.controller"
/>
<
context:component-scan
base-package=
"com.xiaoxie.service"
/>
<!-- 配置消息属性文件 -->
<
bean
class=
"org.springframework.context.support.ResourceBundleMessageSource"
id=
"messageSource"
>
<!-- 资源文件 -->
<
property
name=
"
basenames"
value=
"messages"
/>
<!-- 资源文件的编码格式 -->
<
property
name=
"
defaultEncoding"
value=
"utf-8"
/>
<!-- 资源文件缓存时间:秒 -->
<
property
name=
"
cacheSeconds"
value=
"120"
/>
</
bean
>
<!-- 注册校验器 -->
<
bean
class=
"org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
id=
"validator"
>
<!--
Hibernate
-
validator
-->
<
property
name=
"
providerClass"
value=
"org.hibernate.validator.HibernateValidator"
/>
<!-- 指定校验使用的资源文件 -->
<
property
name=
"
validationMessageSource"
ref=
"messageSource"
/>
</
bean
>
<!-- 开启spring的
Validator
功能 -->
<
mvc:annotation-driven
conversion-service=
"conversionService"
validator=
"validator"
/>
<!-- 注册格式化转换器 -->
<
bean
class=
"org.springframework.format.support.FormattingConversionServiceFactoryBean"
id=
"conversionService"
/>
<!-- 配置视图解析器 -->
<
bean
class=
"org.springframework.web.servlet.view.InternalResourceViewResolver"
id=
"internalResourceViewResolver"
>
<!-- 前缀 -->
<
property
name=
"
prefix"
value=
"/WEB-INF/jsp/"
/>
<!-- 后缀 -->
<
property
name=
"
suffix"
value=
".jsp"
/>
</
bean
>
</
beans
>
注意:在配置messageSource时使用的类是:
org.springframework.context.support.ResourceBundleMessageSource
8.配置web.xml(主要是配置核心的前端控制器:SpringDspatcherServlet)
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<
web-app
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns=
"http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id=
"WebApp_ID"
version=
"2.5"
>
<!-- 前端核心
servlet
的配置(DispatcherServlet) -->
<
servlet
>
<
servlet-name
>springDispatcherServlet
</
servlet-name
>
<
servlet-class
>org.springframework.web.servlet.DispatcherServlet
</
servlet-class
>
<
init-param
>
<
param-name
>contextConfigLocation
</
param-name
>
<
param-value
>classpath:springmvc.xml
</
param-value
>
</
init-param
>
<
load-on-startup
>1
</
load-on-startup
>
</
servlet
>
<!-- Map all requests to the DispatcherServlet for handling -->
<
servlet-mapping
>
<
servlet-name
>springDispatcherServlet
</
servlet-name
>
<
url-pattern
>/
</
url-pattern
>
</
servlet-mapping
>
<!-- 配置解决
psot
请求中文乱码问题 -->
<
filter
>
<
filter-name
>CharacterEncodingFilter
</
filter-name
>
<
filter-class
>org.springframework.web.filter.CharacterEncodingFilter
</
filter-class
>
<
init-param
>
<
param-name
>encoding
</
param-name
>
<
param-value
>
utf-8
</
param-value
>
</
init-param
>
<
init-param
>
<
param-name
>forceEncoding
</
param-name
>
<
param-value
>true
</
param-value
>
</
init-param
>
</
filter
>
<
filter-mapping
>
<
filter-name
>CharacterEncodingFilter
</
filter-name
>
<
url-pattern
>/*
</
url-pattern
>
</
filter-mapping
>
</
web-app
>
9.新增jsp文件:addGoods.jsp、goodsList.jsp
addGoods.jsp:
<%@
page
language=
"java"
contentType=
"text/html; charset=UTF-8"
pageEncoding=
"UTF-8"
%>
<!
DOCTYPE
html
PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>
<
html
>
<
head
>
<
meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<
title
>添加商品
</
title
>
</
head
>
<
body
>
<
form:form
modelAttribute=
"goods"
action=
"${pageContext.request.contextPath }
/goods/save"
method=
"post"
>
<
fieldset
>
<
legend
>添加商品
</
legend
>
<
p
>
<
label
>商品编码:
</
label
>
<
form:input
path=
"gcode"
/>
</
p
>
<
p
>
<
label
>商品名称:
</
label
>
<
form:input
path=
"gname"
/>
</
p
>
<
p
>
<
label
>商品售价:
</
label
>
<
form:input
path=
"gprice"
/>
</
p
>
<
p
>
<
label
>生产日期:
</
label
>
<
form:input
path=
"gdate"
/>(
yyyy-MM-
dd)
</
p
>
<
p
id=
"btn"
>
<
input
id=
"reset"
type=
"reset"
>
<
input
id=
"submit"
type=
"submit"
value=
"添加"
>
</
p
>
<!-- 验证错误信息 -->
<
form:errors
path=
"*"
/>
</
fieldset
>
</
form:form
>
</
body
>
</
html
>
goodsList.jsp:
<%@
page
language=
"java"
contentType=
"text/html; charset=UTF-8"
pageEncoding=
"UTF-8"
%>
<!
DOCTYPE
html
PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>
<
html
>
<
head
>
<
meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<
title
>商品列表
</
title
>
</
head
>
<
body
>
<
table
border=
"1"
cellspacing=
"0"
>
<
tr
>
<
td
>商品编码
</
td
>
<
td
>商品名称
</
td
>
<
td
>商吕价格
</
td
>
<
td
>生产日期
</
td
>
</
tr
>
<
c:forEach
items=
"${goodsList }
"
var=
"goods"
>
<
tr
>
<
td
>${goods.gcode }
</
td
>
<
td
>${goods.gname }
</
td
>
<
td
>${goods.gprice }
</
td
>
<!-- 对日期进行格式化展示 -->
<
td
><
fmt:formatDate
value=
"${goods.gdate }
"
pattern=
"yyyy-MM-dd"
/></
td
>
</
tr
>
</
c:forEach
>
</
table
>
</
body
>
</
html
>
运行工程在“添加”时会对提交的数据做相应的校验,当校验不通过时会在转发到addGoods.jsp页面并且会根据消息配置的信息展示出错误的信息