背景: 在使用struts时我们经常会用到DispatchAction.有了这个类,我们不需要针对每一个Action都要写一个特定的类,而是可以把一些相关的方法放到一个类中. DispatchActon中使用了reflection来根据你传入的method参数的值来获取相应的参数来处理你的请求.正如他的方法 -- 他根据你传入的请求参数,用不同的方法来处理你的请求. 但是,通常我们还会遇到另一种情况,如果我想在之行实际的action处理方法之前或者之后再去做一些别的事情而又不想修改我们实际存在的action类呢?这里我将介绍一种方法. 只要看看struts中DispatchAction(以下简写做DA)的源文件你就会发现,它有一个dispatchMethod方法,接受5个参数.其中4个就是我们通常的struts action里的(mapping,request,response,form),还有一个参数就是指定方法的参数的名字. protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String name) throws Exception 其实现方法如下: // Make sure we have a valid method name to call. // This may be null if the user hacks the query string. if (name == null) { return this.unspecified(mapping, form, request, response); } // Identify the method object to be dispatched to Method method = null; try { method = getMethod(name); } catch (NoSuchMethodException e) { String message = messages.getMessage("dispatch.method", mapping .getPath(), name); log.error(message, e); throw e; } ActionForward forward = null; try { Object args[] = { mapping, form, request, response }; //特殊的url不进行处理(add) String actionUrl = request.getServletPath(); // "/rolesign.do" boolean exception = isException(actionUrl); if(exception) { logger.debug("requestUrl :"+actionUrl+",no pre and post process"); } // 预处理(add) if (!disabled && !exception) { logger.debug("preProcess begin"); preProcess(request); logger.debug("preProcess end"); } forward = (ActionForward) method.invoke(this, args); // 后处理(add) if (!disabled && !exception ){ logger.debug("postProcess begin"); postProcess(request); logger.debug("postProcess end"); } } catch (ClassCastException e) { String message = messages.getMessage("dispatch.return", mapping .getPath(), name); log.error(message, e); throw e; } catch (IllegalAccessException e) { String message = messages.getMessage("dispatch.error", mapping .getPath(), name); log.error(message, e); throw e; } catch (InvocationTargetException e) { // Rethrow the target exception if possible so that the // exception handling machinery can deal with it Throwable t = e.getTargetException(); if (t instanceof Exception) { throw ((Exception) t); } else { String message = messages.getMessage("dispatch.error", mapping .getPath(), name); log.error(message, e); throw new ServletException(t); } } // Return the returned ActionForward instance return (forward); 大部分代码还是从DA的实现方法中copy过来,但是我在这里加入了3个地方.分别是: 1.对请求url的识别,确定是否使用预/后处理 2.预处理方法调用 3.后处理方法调用 当然你要自己写预处理方法和后处理方法.这里你可以传任意你想要的参数给request,然后通过reflection来动态调用任意的java方法,比如你可以在页面设置一个preFunction参数,它的值是classname.methodname.然后你可以在preProcess的实现中通过reflection来查找这个方法并执行. 如果你想让项目中所有的action都有这种特性,则只要让根Action继承DA并覆盖它的dispatchMethod方法即可. 这是在实际项目中用到的一个特性,为了尽可能少的修改原有的代码使用了这种折中的做法.使用reflection时建议不要执行太过复杂的方法,可能会使你的action响应慢的. |
|