Spring框架之拦截器(2.0)
表单验证拦截
拦截器在实际开发之中最大的特点在于服务器端的数据验证处理操作。所有的拦截器的处理实际上都是反射的操作支持。
1,对于进行数据的拦截处理,依然要求在Validators.propertiies文件之中进行定义
*Action名称.方法名称.rules=参数名称:验证类型|参数名称:验证类型|
EmpAction.add.rules=empno:int|ename:string|hiredate:date|sal:double|dept.dname:string
2,定义相应的表单,此时的参数名称一定与验证规则保持一致
<body>
<form action="<%=basePath%>pages/back/emp/empAdd.action" method="post">
雇员编号:<input type="text" id="empno" name="empno" value="7369"><br>
雇员姓名:<input type="text" name="ename" id="ename" value="SMITH"><br>
雇员工资:<input type="text" name="sal" id="sal" value="800.0"><br>
雇佣日期:<input type="text" name="hiredate" id="hiredate" value="1989-10-10"><br>
部门名称:<input type="text" name="dept.dname" id="dept.dname" value="财务部"><br>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
3,所有的验证规则都在资源文件里面编写,而Spring之中资源文件的读取需要依靠在Action中的MessageSource中读取;
*在applicationContext.xml文件里面追加资源的配置:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<array>
<value>Messages</value>
<value>Pages</value>
<value>Validators</value>
</array>
</property>
</bean>
*在Action中需要进行资源对象的注入处理,同时为了方便访问,建议使用getter方法:
@Resource
private MessageSource msgSource ; // 自动匹配注入
public String getSourceMessage(String key) {
return this.msgSource.getMessage(key, null, Locale.getDefault());
}
4,那么在拦截器里面一定需要首先进行资源数据的读取,当然也需要实现key的拼凑。
*实现key的拼凑:
// 2、拼凑要读取的资源文件中的key的内容
String validatorKey = handlerMethod.getBeanType().getSimpleName() + "." + handlerMethod.getMethod().getName() + ".rules" ;
*要想使用指定的Action中的getMsgSource( ),那么必须依靠反射处理,这里面已经存在有了Action类的对象。
//3,取得Action类中对应的getSrouce()方法
Method msgSourceMethod = handlerMethod.getBean().getClass().getMethod("getMsgSrouce");
// 4、取得具体的验证规则
String validateContent = MessageUtil.getMessage(handlerMethod.getBean(), validatorKey) ;
5,当规则取得完成之后,下面还需要进一步观察参数的取得:
*编写一个单独的类,这个类负责具体的验证操作实现;
package cn.mldn.util;
public class ValidatorUtil {
public static boolean isString(String str) {
if (str == null || "".equals(str)) { // 验证失败
return false ;
}
return true ;
}
public static boolean isInt(String str) {
if (ValidatorUtil.isString(str)) { // 数据不为空
return str.matches("\\d+") ;
}
return false ;
}
public static boolean isDouble(String str) {
if (ValidatorUtil.isString(str)) { // 数据不为空
return str.matches("\\d+(\\.\\d+)?") ;
}
return false ;
}
public static boolean isDate(String str) {
if (ValidatorUtil.isString(str)) { // 数据不为空
return str.matches("\\d{4}-\\d{2}-\\d{2}") ;
}
return false ;
}
public static boolean isDatetime(String str) {
if (ValidatorUtil.isString(str)) { // 数据不为空
return str.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}") ;
}
return false ;
}
}
如果要想进行错误的信息编写,那么一定要有相应的错误提示内容,而这个内容可以在Message.properties文件之中进行定义。
invalidate.string.error.msg=\u8BE5\u5B57\u6BB5\u5185\u5BB9\u4E0D\u5141\u8BB8\u4E3A\u7A7A\uFF01
invalidate.int.error.msg=\u8BE5\u5B57\u6BB5\u5185\u5BB9\u5FC5\u987B\u8BBE\u7F6E\u4E3A\u6574\u6570\uFF01
invalidate.double.error.msg=\u8BE5\u5B57\u6BB5\u5185\u5BB9\u5FC5\u987B\u8BBE\u7F6E\u4E3A\u6570\u5B57\uFF01
invalidate.date.error.msg=\u8BE5\u5B57\u6BB5\u5185\u5BB9\u5FC5\u987B\u8BBE\u7F6E\u4E3A\u65E5\u671F\uFF08\u4F8B\u5982\uFF1Ayyyy-mm-dd\uFF09\uFF01
invalidate.datetime.error.msg=\u8BE5\u5B57\u6BB5\u5185\u5BB9\u5FC5\u987B\u8BBE\u7F6E\u4E3A\u65E5\u671F\uFF08\u4F8B\u5982\uFF1Ayyyy-mm-dd hh\:mm\:ss\uFF09\uFF01
·定义一个专门实现资源数据的读取类;
package cn.mldn.util;
import java.lang.reflect.Method;
public class MessageUtil {
public static String getMessage(Object obj, String key) {
try {
Method msgSourceMethod = obj.getClass().getMethod(
"getSourceMessage", String.class);
return (String) msgSourceMethod.invoke(obj, key);
} catch (Exception e) {
e.printStackTrace();
return null ;
}
}
}
随后定义进行具体验证编写的程序类,这个类只是负责出错的信息保存。
package cn.mldn.util;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
public class ValidatorRules {
private Object obj ;
private String rules[];
private HttpServletRequest request;
/**
* @param obj 当前要执行操作的Action程序类
* @param rules 所有的验证规则
* @param request 进行参数的接收处理
*/
public ValidatorRules(Object obj , String rules[], HttpServletRequest request) {
this.obj = obj ;
this.rules = rules;
this.request = request;
}
/**
* 实现具体的验证处理操作
* @return
*/
public Map<String,String> validate() {
Map<String,String> map = new HashMap<String,String>() ;
for (int x = 0 ; x < this.rules.length ; x ++) {
String temp [] = this.rules[x].split(":") ; // 按照竖线拆分
String paramValue = this.request.getParameter(temp[0]) ;
switch(temp[1]) {
case "string" : {
if (!ValidatorUtil.isString(paramValue)) { // 验证失败
map.put(temp[0], MessageUtil.getMessage(this.obj, "invalidate.string.error.msg")) ;
}
break ;
}
case "int" : {
if (!ValidatorUtil.isInt(paramValue)) { // 验证失败
map.put(temp[0], MessageUtil.getMessage(this.obj, "invalidate.int.error.msg")) ;
}
break ;
}
case "double" : {
if (!ValidatorUtil.isDouble(paramValue)) { // 验证失败
map.put(temp[0], MessageUtil.getMessage(this.obj, "invalidate.double.error.msg")) ;
}
break ;
}
case "date" : {
if (!ValidatorUtil.isDate(paramValue)) { // 验证失败
map.put(temp[0], MessageUtil.getMessage(this.obj, "invalidate.date.error.msg")) ;
}
break ;
}
case "datetime" : {
if (!ValidatorUtil.isDate(paramValue)) { // 验证失败
map.put(temp[0], MessageUtil.getMessage(this.obj, "invalidate.datetime.error.msg")) ;
}
break ;
}
}
}
return map ;
}
}
6,map返回有内容,那么就表示有错误,有错误则应该跳转到错误页。
<body>
出错啦!
<h1>${errors}</h1>
</body>