Struts2 的 Validation 拦截器

struts2校验有两种实现方法:
    1. 手工编写代码实现(基本验证)
    2. 基于XML配置方式实现(验证框架)

  • 手工编写代码实现(基本验证)

I:首先 创建一个EmployeeAction类继承于ActionSupport 对应的页面表单元素就一个empId

public class EmployeeAction extends ActionSupport {

private Integer empId;

public void setEmpId(Integer empId) {

System. out.println("setEmpId...." );

this.empId = empId;

}

public String save() {

System. out.println("save....." );

employeeService.save(empId );

return "save-success" ;

}

//手动验证 这个方法是从ActionSupport 中继承得到的 因为ActionSupport 类实现          了Validateable的验证接口

//public class ActionSupport implements Action, Validateable, ValidationAware

@Override

public void validate() {

//这个方法是实现ValidationAware接口得到 给empId 属性手动添加一个错误消息 然后返回到浏览器进行显示

this.addFieldError("empId" , "empId为空值" );

System. out.println("validate....." );

}

}

基本原理:

I:  this .addFieldError("empId" , "empId为空值" );

//ActionSupport 类中

 II: public void addFieldError (String fieldName, String errorMessage) {

validationAware.addFieldError(fieldName, errorMessage);

}

在ValidationAware的实现类中定义了这个方法接口的内容

III:

public class ValidationAwareSupport implements ValidationAware, Serializable {

 private Collection<String> actionErrors ;

private Collection<String> actionMessages ;

private Map<String, List<String>> fieldErrors ;

   public synchronized void addFieldError (String fieldName, String errorMessage) {

Map<String, List<String>> errors = internalGetFieldErrors();获取一个Map集合

//根据fieldName获取一个List集合

List<String> thisFieldErrors = errors.get(fieldName);

if (thisFieldErrors == null) {//判断集合是否为空 为空就创建一个List集合

thisFieldErrors = new ArrayList<String>();

errors.put(fieldName, thisFieldErrors);

}

thisFieldErrors.add(errorMessage);//把fieldName和错误消息 放入集合中

}

这个方法说明最终错误消息添加到fieldErrors Map集合中

     private Map<String, List<String>> internalGetFieldErrors() {

if (fieldErrors == null) {

fieldErrors = new LinkedHashMap<String, List<String>>();

}

return fieldErrors ;

}

}

显示在debug中可以看到

总结:

Action中
    *  要继承ActionSupport
    *  重写Validateable接口中的validate()方法 ,在该方法中完成验证
           * 步骤如下:
                 * validate()方法在其他的业务方法之前执行
                 * 验证出错转向的页面
                         struts.xml配置<result name="input">/validate/XXX.jsp</result>  
                         其中input转向是在action中已经定义好的.
                         public static final String INPUT = "input";

*   什么时候表示验证出错(转向input所指向的页面)
                         *  this.addFieldError("sss", "错误信息");方法指向的是一个集合
                         *  当集合不为空时,转向错误页面.

显示错误Jsp页面:
      使用<s:fielderror/>显示错误消息

补充

validate()方法会校验action中所有与execute方法签名相同的方法。

*  要校验指定的方法通过重写validateXxx()方法实现, validateXxx()只会校验action中
   方法名为Xxx的方法。其中Xxx的第一个字母要大写。

*  当某个数据校验失败时,调用addFieldError()方法往系统的fieldErrors添加校验失败
   信息(为了使用addFieldError()方法,action可以继承ActionSupport ),如果系统
   的fieldErrors包含失败信息,struts2会将请求转发到名为input的result。

*  在input视图中可以通过<s:fielderror/>显示失败信息。
          validateXxx()方法使用例子:

public String add() throws Exception{

return "success";

}

对应的验证方法

public void validateAdd(){

//验证代码

}

在ValidationInterceptor拦截器中可以看到以validate开始的方法

源码中可以看到:

public class ValidationInterceptor extends MethodFilterInterceptor {

    private final static String VALIDATE_PREFIX = "validate";
    private final static String ALT_VALIDATE_PREFIX = "validateDo";

    protected void doBeforeInvocation(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();
        ActionProxy proxy = invocation.getProxy();

        String context = this.getValidationContext(proxy);
        String method = proxy.getMethod();

        if (declarative ) {
           if (validateAnnotatedMethodOnly ) {
               actionValidatorManager.validate(action, context, method);
           } else {
               actionValidatorManager.validate(action, context);
           }
       }
        if (action instanceof Validateable && programmatic) {

            Exception exception = null;

            Validateable validateable = (Validateable) action;

            try {
                    //这个和Preparable 拦截器原理相同

                  //在这里获取带有方法前缀的的方法 进行调用
             //  VALIDATE_PREFIX = "validate" ;
            //ALT_VALIDATE_PREFIX = "validateDo" ;

                PrefixMethodInvocationUtil.invokePrefixMethod(
                                invocation,
                                new String[] { VALIDATE_PREFIX , ALT_VALIDATE_PREFIX });
            }
            catch(Exception e) {
                exception = e;
            }

        }
    }

    @Override
    protected String doIntercept(ActionInvocation invocation) throws Exception {
        doBeforeInvocation(invocation);
        return invocation.invoke();
    }
}

public class PrefixMethodInvocationUtil {

public static void invokePrefixMethod (ActionInvocation actionInvocation, String[] prefixes) {
          Object action = actionInvocation.getAction();
          String methodName = actionInvocation.getProxy().getMethod();
           if (methodName == null) {
             methodName = DEFAULT_INVOCATION_METHODNAME;
          }
          //获取带前缀的方法
          Method method = getPrefixedMethod(prefixes, methodName, action);
           if (method != null) {
               //调用对应的action方法
              method.invoke(action, new Object[0]);
          }
     }
}
//获取带前缀的方法
public class PrefixMethodInvocationUtil {

public static Method getPrefixedMethod (String[] prefixes, String methodName, Object action) {
           assert(prefixes != null);
          String capitalizedMethodName = capitalizeMethodName(methodName);
        for (String prefixe : prefixes) {
            String prefixedMethodName = prefixe + capitalizedMethodName;
            try {
                return action.getClass().getMethod(prefixedMethodName, EMPTY_CLASS_ARRAY);
            }
            catch (NoSuchMethodException e) {
                 e
            }
        }
           return null ;
     }

}

输入校验的流程:

1。类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性。

2。如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext,conversionError拦截器将异常信息封装到fieldErrors里,然后执行第3步。如果类型转换没有出现异常,则直接进入第3步。

3。系统通过反射技术调用action中的validateXxx()方法,Xxx为方法名。

4。调用action中的validate()方法。

5。经过上面4步,如果系统中的fieldErrors存在错误信息(即存放错误信息的集合的size大于0),系统自动将请求转发至名称为input的视图。如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法。

时间: 2024-11-06 07:06:48

Struts2 的 Validation 拦截器的相关文章

Struts2 之 Validation 拦截器 基于XML配置方式实现(验证框架)

基于XML配置方式实现输入校验 I:定义Action *  要继承ActionSupport或者实现Validateable接口: II:配置struts_validate.xml文件 *  验证出错转向的页面                struts.xml配置<result name=“input”>/validate/loginxml.jsp</result>                  其中input转向是在action中已经定义好的. III:配置验证的xml文件

Struts2内置拦截器的简要介绍

标记有(*)要着重了解: (1)alias(别名拦截器):允许参数在跨越多个请求时使用不同别名,该拦截器可将多个Action采用不同名字链接起来,然后用于处理同一信息. (2)autowiring(自动装配拦截器):主要用于当Struts2和Spring整合时,Struts2可以使用自动装配的方式来访问Spring容器中的Bean. (3)(*)chain(链拦截器):构建一个Action链,使当前Action可以访问前一个Action的请求信息,一般和<result type="chai

关于struts2的自定义拦截器和struts2的详细流程

1.其实我们大家平常都会用struts2用的很多,但是有的时候我们并不是真正的了解struts2的运行机制,下面给大家分享一下struts2的运行流程.MVC框架 解释如下: 1.  所有请求被Struts2核心控制器StrutsPreparaedAndExecuteFilter拦截 2.根据ActionMapper提供的信息决定如何进行下一步 3.ActionMapper主要依赖Struts2的配置文件struts.xml 4.接下来为每个Action创建Action代理类ActionProx

(转)关于struts2的自定义拦截器和struts2的详细流程

转自 http://www.94cto.com/index/Article/content/id/63218.html.话说,写的真不错. 1.其实我们大家平常都会用struts2用的很多,但是有的时候我们并不是真正的了解struts2的运行机制,下面给大家分享一下struts2的运行流程.MVC框架 解释如下: 1. 所有请求被Struts2核心控制器StrutsPreparaedAndExecuteFilter拦截 2.根据ActionMapper提供的信息决定如何进行下一步 3.Actio

struts2入门之拦截器

1.拦截器的执行时间:在action对象创建之后,在具体的方法执行之前: 2.拦截器底层实现原理:用到AOP思想和责任链模式:AOP:面向切面编程,通俗的讲就是当某个功能模块要增加某一项功能时,尽可能不去修改源代码而是通过其他的方式来达到相同的效果,比如通过配置文件等方式:责任链模式和过滤链模式有点相似,过滤链模式是指比如,一个请求由多个过滤器进行过滤,每个过滤器进行放行之后才能到下一个过滤器,最后实现目的:但是责任链模式,比如要执行多个操作,有添加,修改,删除三个操作,首先执行添加操作,添加操

【struts2】struts2的execAndWait拦截器使用

使用execAndWait拦截器可以在等待较长时间的后台处理中增加等待页面.实现如下图所示的效果: 1)struts.xml主要部分 <action name="test" class="actions.ActionDemo" method="queryall"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="

struts2内置拦截器和自定义拦截器详解(附源码)

一.Struts2内置拦截器 Struts2中内置类许多的拦截器,它们提供了许多Struts2的核心功能和可选的高级特 性.这些内置的拦截器在struts-default.xml中配置.只有配置了拦截器,拦截器才可以正常的工作和运行.Struts 2已经为您提供丰富多样的,功能齐全的拦截器实现.大家可以至struts2的jar包内的struts-default.xml查看关于默认的拦截器与 拦截器链的配置.内置拦截器虽然在struts2中都定义了,但是并不是都起作用的.因为并不是所有拦截器都被加

Struts2(十四)拦截器实现权限管理

一.认识拦截器 拦截器也是一个类 拦截器可以在Action被调用之前和之后执行代码 框架很多核心功能是拦截器实现的 拦截器的特点: 拦截器自由组合,增强了灵活性.扩展性.有利于系统解耦 拦截器可以拦截Action请求 在访问的Action执行之前和执行之后执行代码实现某项功能 Struts2: 大部分功能是在拦截器中实现的如:接收输入的参数,数据验证,文件上传,国际化等 应用程序: 需要在Action执行的前后执行特定功能 Action执行时间统计,Action访问权限管理 Action添加功能

Struts2自己定义拦截器实例—登陆权限验证

版本号:struts2.1.6 此实例实现功能:用户须要指定username登陆,登陆成功进入对应页面运行操作,否则返回到登陆页面进行登陆,当直接訪问操作页面(登陆后才干訪问的页面)时则不同意,须返回登陆页面. 代码例如以下: 一.页面 login.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUB