http://blogwarning.iteye.com/blog/1390172
在struts2的struts-default.xml中定义了一个name为prepare拦截器,实现类是com.opensymphony.xwork2.interceptor.PrepareInterceptor,它的作用是为实现了com.opensymphony.xwork2.Preparable接口的action调用相关方法。该拦截器有两个参数:alwaysInvokePrepare,firstCallPrepareDo,两者的类型都是boolean,默认值分别是true,false。
该拦截器的核心代码如下:
- public String doIntercept(ActionInvocation invocation) throws Exception {
- Object action = invocation.getAction();
- if (action instanceof Preparable) {
- try {
- String[] prefixes;
- if (firstCallPrepareDo) {
- prefixes = new String[] {ALT_PREPARE_PREFIX, PREPARE_PREFIX};
- } else {
- prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX};
- }
- PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);
- }
- catch (InvocationTargetException e) {
- /*
- * The invoked method threw an exception and reflection wrapped it
- * in an InvocationTargetException.
- * If possible re-throw the original exception so that normal
- * exception handling will take place.
- */
- Throwable cause = e.getCause();
- if (cause instanceof Exception) {
- throw (Exception) cause;
- } else if(cause instanceof Error) {
- throw (Error) cause;
- } else {
- /*
- * The cause is not an Exception or Error (must be Throwable) so
- * just re-throw the wrapped exception.
- */
- throw e;
- }
- }
- if (alwaysInvokePrepare) {
- ((Preparable) action).prepare();
- }
- }
- return invocation.invoke();
- }
该代码的逻辑非常简单,如果action实现了com.opensymphony.xwork2.Preparable接口,则在调用setXXX和execute()方法之前调用系列方法。如果firstCallPrepareDo为true,则调用prepareDoXXX方法,否则调用prepareXXX方法(XXX为action对应的方法)。接下来查看alwaysInvokePrepare状态,如果其值为true则调用com.opensymphony.xwork2.Preparable接口的prepare方法。最后将action转交给下一个拦截器。