任何软件系统的开发,都必须考虑输入数据的有效性问题,即要保证非法的数据不被系统接收,又要有较好的用户操作体验。B/S系统的开发更是如此,数据的验证至少都要建立起:客户端和服务器端两道防线。建立客户端验证机制是为了加快验证速度,提高用户交互效率,而服务器端验证将是数据必经之路,这道关卡是必不可少的。
B/S系统中的表现层框架中,struts2是一个即能自动生成客户端,又能生成服务器端数据验证代码的框架,这点非常可贵,但是必须要引用struts2的自定标记库。struts1和struts2的验证,都是通过在xml文件中配置formbean的中每一个字段的验证规则以及出错提示消息,结合相应的标记库,可以显示服务器端的验证结果,并且通过标记库,可以保留(回填)用户之前输入的数据。
因此,我们在开发中要考虑三个问题,一是页面上哪些输入元素用什么样的验证规则,二是出错后如何在页面上显示出错信息,三是用户之前输入的数据回填(避免用户重新再输入)。
我之前在一些小项目中都是不主张引入验证框架的,输入表单不算太复杂,由程序员手工if esle 做验证,并将验证信息放入request中。但对于大、中型项目,这种做法显然并不规范。我们用DTO(VO)接收页面表单数据,之后根据配置的验证规则对表单数据进行验证,如果满足验证规则执行后面的业务处理,否则回填数据,并向用户报告未通过验证的原因。
下面我们一起来看看spring mvc中是如何做的。spring mvc通过JSR 303规范对java bean字段验证定义,通过注解配置来实现对数据的合法性验证。JSR 303目前有jboss和hibernate的两个实现,我们在这里采用hibernate的实现。
先要在项目中导入validation-api-1.0.0.GA.jar和hibernate-validator-4.1.0.Final.jar两个包,之后就在DTO(VO)中对需要验证的字段进行配置了(如果页面字段内容和领域模型中的POJO字段一致,可以不必定义新的DTO(VO)对象,直接使用POJO即可),示例代码如下:
public class Student implements Serializable {
//姓名
@NotEmpty(message="姓名不可以为空!")
@Length(min=2,max=5)
private String name;
//出生日期
@Past(message="生日输入不正确,请核对!")
private Date birthday;
先来看上面代码中的name字段,我们用了@NotEmpty注解,标明此字段不能为空,如果为空将显示由message指定的消息,如果想指定资源文件中的消息key,可以用NotEmpty.modelname.fieldname指定,modelname是DTO对象在spring mvc作用域中的名称,fieldname是字段属性名。
@Length指定该字段的长度区间,在这里我没有指定默认消息,系统将使用内置的默认消息(英文的),当然你可以在资源文件中指定消息key,比如,在资源文件中定义:Length.student.name = 用户的姓名长度必须在 2 到 5之间!。
@Past注解标明该日期必须在今天以后。
更多更复杂的验证规则配置,大家可参考下面表格的描述(转自hiberante validator官网):
Annotation
Part of Bean Validation Specification
Apply on
Use
Hibernate Metadata impact
@AssertFalse |
yes |
field/property |
check that the annotated element is false. |
none |
@AssertTrue |
yes |
field/property |
check that the annotated element is true. |
none |
@DecimalMax |
yes |
field/property. Supported types are BigDecimal, BigInteger, String, byte, short, int, long and the respective wrappers of the primitive types. |
The annotated element must be a number whose value must be lower or equal to the specified maximum. The parameter value is the string representation of the max value according to the BigDecimal string representation. |
none |
@DecimalMin |
yes |
field/property. Supported types are BigDecimal, BigInteger, String, byte, short, int, long and the respective wrappers of the primitive types. |
The annotated element must be a number whose value must be higher or equal to the specified minimum. The parameter value is the string representation of the min value according to the BigDecimal string representation. |
none |
@Digits(integer=, fraction=) |
yes |
field/property. Supported types are BigDecimal, BigInteger, String, byte, short, int, long and the respective wrappers of the primitive types. |
Check whether the property is a number having up to integer digits and fraction fractional digits. |
Define column precision and scale. |
@Email |
no |
field/property. Needs to be a string. |
Check whether the specified string is a valid email address. |
none |
@Future |
yes |
field/property. Supported types are java.util.Date and java.util.Calendar. |
Checks whether the annotated date is in the future. |
none |
@Length(min=, max=) |
no |
field/property. Needs to be a string. |
Validate that the annotated string is between min and max included. |
none |
@Max |
yes |
field/property. Supported types are BigDecimal, BigInteger, String, byte, short, int, long and the respective wrappers of the primitive types. |
Checks whether the annotated value is less than or equal to the specified maximum. |
Add a check constraint on the column. |
@Min |
yes |
field/property. Supported types are BigDecimal, BigInteger, String, byte, short, int, long and the respective wrappers of the primitive types. |
Check whether the annotated value is higher than or equal to the specified minimum. |
Add a check constraint on the column. |
@NotNull |
yes |
field/property |
Check that the annotated value is not null. |
Column(s) are not null. |
@NotEmpty |
no |
field/property. Needs to be a string. |
Check if the string is not null nor empty. |
none |
@Null |
yes |
field/property |
Check that the annotated value is null. |
none |
@Past |
yes |
field/property. Supported types are java.util.Date and java.util.Calendar. |
Checks whether the annotated date is in the past. |
none |
@Pattern(regex=, flag=) |
yes |
field/property. Needs to be a string. |
Check if the annotated string match the regular expression regex. |
none |
@Range(min=, max=) |
no |
field/property. Supported types are BigDecimal, BigInteger, String, byte, short, int, long and the respective wrappers of the primitive types. |
Check whether the annotated value lies between (inclusive) the specified minimum and maximum. |
none |
@Size(min=, max=) |
yes |
field/property. Supported types are String, Collection, Map and arrays. |
Check if the annotated element size is between min and max (inclusive). |
Column length will be set to max. |
@Valid |
yes |
field/property |
Perform validation recursively on the associated object. |
再来看看action中新增学生的代码中,是如何进行数据验证的:
/**
* 添加学生信息
* @return String
*/
@RequestMapping(params="add")
public String addStudent(ModelMap model,
@RequestParam(value="pno",defaultValue="1")int pno,
@ModelAttribute("student") @Valid Student stu,
BindingResult result) {
if (result.hasErrors()) {
return "add_student";
}
Student student = new Student();
//将页面属性拷贝到student中
BeanUtils.copyProperties(stu, student, new String[]{});
try {
studentService.addStudent(student);
} catch (BizException e) {
model.put("error_key", e.getMessage());
return "error";
}
return "redirect:student.action?page&pno=" + pno;
}
上面的代码@ModelAttribute(“student”) @Valid Student stu中,我们用@Valid注解标明,页面传入的 Student stu必须要验证,规则当然是我们前面用注解定义过的了。
如果验证没有通过,我们怎么能够知道呢?BindingResult result,看到这个参数了么,这个里面有验证是否通过的信息,我们用result.hasErrors()就可以知道验证是否通过,如果没有通过,则转到出错的页面。
最后一个问题,页面中如果显示这个错误信息呢?需要引入
<!--taglib uri="/WEB-INF/spring-form.tld" prefix="form"-->
标记库,这个是spring mvc定义的。比如对姓名的错误显示,我们通过
<form:errors path="student.name"/>
就可以显示这个字段的验证出错信息了。
有人说,引入spring mvc的标签库,似乎在jsp中产生了和spring mvc的耦合。确实如此,天下没有免费的午餐,你想想,其它的mvc验证框架,不是也要引入相应的视图标签库么。spring mvc将org.springframework.validation.BindingResult.modelAttributeName名作为key保存出错的信息,本例中用org.springframework.validation.BindingResult.student为key保存了一个org.springframework.validation.BeanPropertyBindingResult的错误对象,如果用EL表达式来取出错的信息,还真取不出来。
数据的回填问题非常简单,直接访问作用域中的modelAttributeName的对象就可以了,本例中是studnet,姓名的页面元素,就可以写成:
<input type='text' name="name" value="${student.name}"/>
分享到:
相关推荐
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring MVC4是当前zuixin的版本,在众多特性上有了进一步的提升。, 在精通Spring...
Spring MVC 是一个基于Java的轻量级Web应用框架,它为开发者提供了模型-视图-控制器(MVC)架构,使开发人员能够更好地组织和分离应用程序的业务逻辑、数据处理和用户界面。Spring MVC是Spring框架的一个核心组件,...
Spring MVC 是一款强大的Java Web开发框架,用于构建高效、可维护和模块化的Web应用程序。它作为Spring框架的一部分,提供了一种优雅的方式来处理HTTP请求和响应,使得开发者可以专注于业务逻辑而不是底层实现。在这...
Spring MVC是Spring框架的一个核心模块,专为构建Web应用程序而设计。它提供了模型-视图-控制器(MVC)架构,使开发者能够有效地分离业务逻辑、数据处理和用户界面。在"Spring MVC 4.2.3"版本中,我们看到了一系列的...
Spring MVC是Spring框架的一个核心模块,专为构建Web应用程序提供模型-视图-控制器(MVC)架构。在Spring MVC 4.0版本中,它引入了许多改进和新特性,以提升开发效率和应用程序的性能。 1. **依赖注入**:Spring ...
Spring MVC 是一个强大的Java Web开发框架,它是Spring框架的一部分,专为构建高度可扩展和模块化的Web应用程序而设计。在2015年的版本中,Spring MVC 4已经相当成熟,提供了许多特性来简化开发流程并提高开发效率。...
二、Spring MVC核心类与接口:Spring MVC架构中包含许多核心组件,如DispatcherServlet、HandlerMapping、Controller、ViewResolver等。这些组件协同工作,处理用户的请求并返回相应的响应。 三、Spring MVC核心...
Spring MVC 是一个基于Java的轻量级Web应用框架,它是Spring框架的重要组成部分,主要用于构建Web应用程序的后端控制器。这个教程“Spring MVC - A Tutorial”旨在帮助开发者深入理解和掌握Spring MVC的核心概念和...
Spring MVC 是一个基于 Java 的轻量级Web应用框架,它为构建模型-视图-控制器(MVC)架构的应用程序提供了强大的支持。在本压缩包中包含了一系列与Spring MVC相关的jar文件,这些文件是构建和运行Spring MVC项目所...
Spring MVC是Spring框架的一个核心模块,专用于构建Web应用程序。这个"Spring MVC使用Demo"提供了实践操作,帮助开发者深入理解Spring MVC的开发环境配置、注解的使用以及工作原理。 首先,Spring MVC的设计模式...
这是一个基于Spring MVC、Mybatis和Spring框架实现的个人博客系统,涵盖了Web开发中的后端架构设计、数据库管理和前端展示等多个方面。以下将详细介绍这个系统的关键知识点: **1. Spring MVC** Spring MVC是Spring...
Spring MVC 是一个基于 Java 的轻量级 Web 开发框架,它是 Spring 框架的一个重要模块,主要用于构建 Web 应用程序的后端控制层。这个框架提供了模型-视图-控制器(MVC)设计模式的实现,简化了Java Web应用的开发...
Spring MVC 是一个基于Java的轻量级Web应用框架,它是Spring框架的重要组成部分,主要用于构建Web应用程序的后端控制器。Spring MVC的设计目标是提供一个清晰的组件化架构,使得开发者可以独立地开发和测试控制器、...
Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)SSM源码Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)SSM源码Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)SSM源码Java EE企业级应用...
### Spring MVC 教程知识点详解 #### Spring Web MVC 框架简介 Spring Web MVC 是 Spring Framework 的一个重要组成部分,主要用于构建基于 Java 的 Web 应用程序。它提供了一个灵活且强大的 MVC 实现,使得开发者...
在本项目中,我们主要探讨的是如何利用Spring MVC和Spring Security框架构建一个基本的无数据库登录系统。Spring MVC是Spring框架的一部分,用于处理Web应用程序的请求-响应模型,而Spring Security则是一个强大的...
Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于...