SpringMVC和FreeMarker整合中使用注解方式的后台数据校验

本文介绍如何在SpringMVC与FreeMarker整合的项目中使用JSR-303验证框架进行数据校验,包括配置步骤、JavaBean注解使用、控制器校验逻辑及FreeMarker错误信息展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringMVC和FreeMarker整合中使用注解方式的后台数据校验

源自:http://yunzhu.iteye.com/blog/2088548

 

前提概要

本文主题:

在Spring MVC和FreeMarker整合的项目中,采用JSR-303验证框架,通过注解的方式进行数据验证

 

基础框架:

MVC:Spring MVC 3

视图:FreeMarker

验证:Hibernate-validator实现

 

需要JAR包:

0、Spring MVC和FreeMarker所需jar包

1、org.hibernate.validator-4.1.0.GA.jar

2、javax.validation-1.0.0.GA.jar

 

 

配置文件和Java代码的修改

 

在Spring MVC配置文件中添加配置

添加以下mvc的注解驱动配置,一切变成“自动化”

Xml代码 复制代码  收藏代码
  1. <mvc:annotation-driven />  

 

 

在JavaBean中添加数据校验的注解

其中@Length、@Email就是Hibernate-validator中的数据校验注解,还可以用javax.validation中的注解,比如@NotNull

Java代码 复制代码  收藏代码
  1. public class SystemUser {  
  2.     @Length(min = 5, max = 20, message = "用户名长度必须位于5到20之间")  
  3.     private String userName;  
  4.   
  5.     @Email(message = "比如输入正确的邮箱")  
  6.     private String email;  
  7. }  
public class SystemUser {
	@Length(min = 5, max = 20, message = "用户名长度必须位于5到20之间")
	private String userName;

	@Email(message = "比如输入正确的邮箱")
	private String email;
}

 

 

在Controller方法中指定需要进行校验

首先,要在需要进行校验的Bean前面加上@Valid注解,告诉SpringMVC框架这个Bean需要进行校验;

同时,还要在需要校验的Bean前面加上@ModelAttribute注解,从而将Bean暴露给视图,并且指定名字,这有两个作用,第一是显示校验错误需要使用这个名字,第二个是返回原来的页面以后,前面输入的所有值还要显示出来;

其次,每个需要校验的Bean后面紧跟一个BindingResult,SpringMVC框架会将校验结果保存在它里面,通过hasErrors方法可以判断是否有校验错误;

最后,当返回到原页面以后,SpringMVC框架还会将所有校验错误信息保存在上下文中,供页面上取得校验错误,Spring提供了一套JSP自定义标签。

Java代码 复制代码  收藏代码
  1. @RequestMapping(value = "/create.html", method = RequestMethod.POST)  
  2. public String doCreateUser(  
  3.         @Valid @ModelAttribute("userDetail") SystemUser user,  
  4.         BindingResult bindingResult,  
  5.         HttpServletRequest request) {  
  6.     // 如果有校验错误,返回添加用户的页面  
  7.     if (bindingResult.hasErrors()) {  
  8.         return "/user/create";  
  9.     }  
  10.       
  11.     this.userService.createUser(user);  
  12.     return "/user/list.html";  
  13. }  
@RequestMapping(value = "/create.html", method = RequestMethod.POST)
public String doCreateUser(
		@Valid @ModelAttribute("userDetail") SystemUser user,
		BindingResult bindingResult,
		HttpServletRequest request) {
	// 如果有校验错误,返回添加用户的页面
	if (bindingResult.hasErrors()) {
		return "/user/create";
	}
	
	this.userService.createUser(user);
	return "/user/list.html";
}

 

 

进行自定义校验

如果需要添加自定义校验,比如验证用户名是否已经被使用了,那么简单的注解自然无能为力,需要自己编码实现,如果校验失败,可以手动将自定义校验错误添加到BindingResult中。

Java代码 复制代码  收藏代码
  1. @RequestMapping(value = "/user/create.html", method = RequestMethod.POST)  
  2. public String doCreateUser(  
  3.         @Valid @ModelAttribute("userDetail") SystemUser user,  
  4.         BindingResult bindingResult,  
  5.         HttpServletRequest request) {  
  6.     // 如果有数据校验错误,返回添加用户的页面  
  7.     if (bindingResult.hasErrors()) {  
  8.         return "/user/create";  
  9.     }  
  10.   
  11.     boolean isUserNameExist = this.userService.checkUserByUserName(user.getUserName());  
  12.     // 如果用户名已存在,返回添加用户的页面  
  13.     if (isUserNameExist) {  
  14.         // 向BindingResult添加用户已存在的校验错误  
  15.         bindingResult.rejectValue("userName""该用户名已存在""该用户名已存在");  
  16.         return "/user/create";  
  17.     }  
  18.       
  19.     this.userService.createUser(user);  
  20.     return "/user/list.html";  
  21. }  
@RequestMapping(value = "/user/create.html", method = RequestMethod.POST)
public String doCreateUser(
		@Valid @ModelAttribute("userDetail") SystemUser user,
		BindingResult bindingResult,
		HttpServletRequest request) {
	// 如果有数据校验错误,返回添加用户的页面
	if (bindingResult.hasErrors()) {
		return "/user/create";
	}

	boolean isUserNameExist = this.userService.checkUserByUserName(user.getUserName());
	// 如果用户名已存在,返回添加用户的页面
	if (isUserNameExist) {
		// 向BindingResult添加用户已存在的校验错误
		bindingResult.rejectValue("userName", "该用户名已存在", "该用户名已存在");
		return "/user/create";
	}
	
	this.userService.createUser(user);
	return "/user/list.html";
}

 

 

 

在JSP页面上显示校验错误信息

返回页面以后,SpringMVC框架将所有校验错误信息都放在了上下文中,可以自己去取出来,但是那样非常麻烦,不过没关系,Spring提供了一套自定义标签,可以方便的显示校验错误信息。

 

页面头部需要导入Spring的自定义标签库

Html代码 复制代码  收藏代码
  1. <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>  
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

 

 

 

需要一次性显示全部校验错误

(commandName的值就是@ModelAttribute注解中指定的值)

Html代码 复制代码  收藏代码
  1. <form:form commandName="userDetail">  
  2.     <form:errors path="*" cssStyle="color:red"></form:errors>  
  3. </form:form>  
<form:form commandName="userDetail">
    <form:errors path="*" cssStyle="color:red"></form:errors>
</form:form>

 

 

 

需要在对应输入框的后面显示单个校验错误

(通过path指定显示那个具体的校验错误,userDetail正是@ModelAttribute注解中指定的值,而点号后面则是指定显示Bean中哪个属性的校验错误)

Html代码 复制代码  收藏代码
  1. <input type="text" name="userName" value="${userDetail.userName}" >  
  2. <form:errors path="userDetail.userName" cssStyle="color:red"></form:errors>  
  3.   
  4. <input type="text" name="email" value="${userDetail.email}">  
  5. <form:errors path="userDetail.email" cssStyle="color:red"></form:errors>  
<input type="text" name="userName" value="${userDetail.userName}" >
<form:errors path="userDetail.userName" cssStyle="color:red"></form:errors>

<input type="text" name="email" value="${userDetail.email}">
<form:errors path="userDetail.email" cssStyle="color:red"></form:errors>

 

 

 

在FreeMarker视图上面显示校验错误

如果视图使用的是FreeMarker,Spring同样提供了一套“自定义标签库”,在FreeMarker中叫做自定义宏,使我们可以方便的显示出校验错误信息。

 

所有首先,需要导入Spring专门为FreeMarker提供的宏指令文件

Html代码 复制代码  收藏代码
  1. <#import "spring.ftl" as spring />  
<#import "spring.ftl" as spring />

 

 

然后就可以在每个输入框后面显示单个校验错误了

(bind后面的值与JSP中显示校验错误时的path是一致的)

Html代码 复制代码  收藏代码
  1. <input type="text" name="userName" value="${(userDetail.userName)!}" />  
  2. <#if userDetail??>  
  3.     <@spring.bind "userDetail.userName" />  
  4.     <@spring.showErrors "<br>"/>  
  5. </#if>  
  6.   
  7. <input type="text" name="email" value="${(userDetail.email)!}" />  
  8. <#if userDetail??>  
  9.     <@spring.bind "userDetail.email" />  
  10.     <@spring.showErrors "<br>"/>  
  11. </#if>  
<input type="text" name="userName" value="${(userDetail.userName)!}" />
<#if userDetail??>
	<@spring.bind "userDetail.userName" />
	<@spring.showErrors "<br>"/>
</#if>

<input type="text" name="email" value="${(userDetail.email)!}" />
<#if userDetail??>
	<@spring.bind "userDetail.email" />
	<@spring.showErrors "<br>"/>
</#if>

 

 

如何在FreeMarker模版文件中显示单个的校验错误信息?

<@spring.bind "userDetail.email" /> :是绑定到具体哪一个字段的校验结果,

<@spring.showErrors "<br>"/>         :则显示校验错误信息

 

在整合SpringMVC和FreeMarker搭建基础框架的过程中,基本顺风顺水,如今各种脚手架到处都是,拿几个过来参照即可。唯一花了点精力研究的就是——如何在FreeMarker模版文件中显示单个的校验错误信息。针对这个问题,在网上找了不少时间,都没有找到合适的方法,最后还是在国外的技术论坛上看到这个方法。这才是写下这篇博客的动力所在,希望对您有所帮助。

 

 

写在后面的话

如今Web系统都有前台JS校验,比如使用jQuery的validate框架就非常方便,所以上述在页面上显示校验错误信息的工作其实不是必须的。有了前台JS校验就能保证正常用户体验没有问题了,但是不能防止非正常用户绕过JS校验的恶意请求,所以后台校验还是要做的。我们只需要在Controller方法里面判断有校验错误的时候直接返回到一个错误页面就行了,那样就能保证所有请求数据都会经过校验,不管是经过了前台JS校验合格的数据,还是有人通过工具绕过JS校验的恶意数据,都难逃法眼。

width="468" height="60" src="http://yunzhu.iteye.com/iframe_ggbd/794" frameborder="0" scrolling="no">    

0
0
    
分享到:                  
评论
    
10 楼     yunzhu    2015-03-16            
xvhua4317 写道
太棒了,简单直接

谢谢
9 楼     xvhua4317    2015-03-13            
太棒了,简单直接
8 楼     yunzhu    2014-08-17            
SmileToYou 写道
感谢了

不客气
7 楼     SmileToYou    2014-08-17            
感谢了
6 楼     yunzhu    2014-08-17            
LinApex 写道
yunzhu 写道
LinApex 写道
完全没意思,绑定的太死了.

在实际项目中后来也没有在页面上面显示服务端校验错误消息,只是在Controller方法里面进行了校验然后返回到错误页面。不过JSR-303还是很有用的,让校验形成标准


我的意思是说,后台返回错误消息,还需要在前端写各种标签,各种麻烦,我改进了功能,将错误信息封装成json返回给前端,前端再提示错误信息。 这样体验更好一些,任何人也绕不过验证.

嗯,这种体验是比较好,具体怎么实现的,可以讨教一下吗
5 楼     yunzhu    2014-08-17            
SmileToYou 写道
能把jsr303需要的jar给我一份吗?我下载的就只有hibernate-validation.jar

附件添加了一个javax.validation-1.0.0.GA.jar
    4 楼     SmileToYou    2014-08-16            
能把jsr303需要的jar给我一份吗?我下载的就只有hibernate-validation.jar
    3 楼     LinApex    2014-07-05            
yunzhu 写道
LinApex 写道
完全没意思,绑定的太死了.

在实际项目中后来也没有在页面上面显示服务端校验错误消息,只是在Controller方法里面进行了校验然后返回到错误页面。不过JSR-303还是很有用的,让校验形成标准


我的意思是说,后台返回错误消息,还需要在前端写各种标签,各种麻烦,我改进了功能,将错误信息封装成json返回给前端,前端再提示错误信息。 这样体验更好一些,任何人也绕不过验证.
2 楼     yunzhu    2014-07-05            
LinApex 写道
完全没意思,绑定的太死了.

在实际项目中后来也没有在页面上面显示服务端校验错误消息,只是在Controller方法里面进行了校验然后返回到错误页面。不过JSR-303还是很有用的,让校验形成标准
1 楼     LinApex    2014-07-05            
完全没意思,绑定的太死了.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值