Struts2拦截器之DefaultWorkflowInterceptor

时间:2022-02-22 21:43:15

1  /** 
2  * DefaultWorkflowInterceptor:
3
* 处于默认的拦截器栈最后的位置,用来判断Action的执行过程中有无错误 4 * 5 * **/ 6 public class DefaultWorkflowInterceptor extends MethodFilterInterceptor { 7 8 private static final long serialVersionUID = 7563014655616490865L; 9 10 //日志 11 private static final Logger LOG = LoggerFactory.getLogger(DefaultWorkflowInterceptor.class); 12 13 //酱油位,大概是为了避免每次都创建的话会很浪费吧(注意是static的哦) 14 private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; 15 16 //表示要求重新输入的字符,当检查出问题的时候就返回这个字符串让用户重新输入 17 private String inputResultName = Action.INPUT; 18 19 /** 20 * Set the <code>inputResultName</code> (result name to be returned when 21 * a action / field error is found registered). Default to {@link Action#INPUT} 22 * 23 * @param inputResultName what result name to use when there was validation error(s). 24 */ //在配置的时候可以传入一个inputResultName的param,,会通过这个方法设置进来的 25 public void setInputResultName(String inputResultName) { 26 this.inputResultName = inputResultName; 27 } 28 29 /** 30 * Intercept {@link ActionInvocation} and returns a <code>inputResultName</code> 31 * when action / field errors is found registered. 32 * 33 * @return String result name 34 */ 35 @Override 36 protected String doIntercept(ActionInvocation invocation) throws Exception { 37 38 //先获得当前的action对象 39 Object action = invocation.getAction(); 40 41 //判断这个action是否实现了ValidationAware接口,意思就是看看当前的action需不需要验证 42 if (action instanceof ValidationAware) { 43 44 //首先进行类型转换,类型转换后的action就会被当做ValidationAware处理了,下面就称这个action对象为ValidationAware实例 45 ValidationAware validationAwareAction = (ValidationAware) action; 46 47 //如果这个ValidationAware实例中已经包含了错误信息,就进行一些操作然后把拦截器执行栈咔嚓掉,然后直接返回特定字串(默认是Action.INPUT) 48 if (validationAwareAction.hasErrors()) { 49 50 //是否记录日志 51 if (LOG.isDebugEnabled()) { 52 LOG.debug("Errors on action " + validationAwareAction + ", returning result name ‘input‘"); 53 } 54 55 //默认的返回字串为Action.INPUT,是写死的,不过没关系我们后面可以通过实现ValidationWorkflowAware接口来自定义 56 String resultName = inputResultName; 57 58 /*Action可以实现ValidationWorkflowAware然后实现getInputResultName():String方法来自定义当发生错误的时候的返回字串 59 比如实现不同的方法验证出处返回不同的字串,只需要在检验出错的时候设定一个成员变量的值然后在getInputResultName()返回其值就可以了,比如 60 在create方法中出错将事先声明的成员变量inputResultName设定为“create”,而在delete中出错将inputResultName设定为“delete”,这样就可以区分它们并可以跳转到不同的页面啦 61 但这只是一种折中的办法,一个良好的规范是ValidationWorkflowAware提供了方法级别的自定义返回字串,而@InputConfig提供了方法级别的自定义返回字串 62 */ 63 if (action instanceof ValidationWorkflowAware) { 64 resultName = ((ValidationWorkflowAware) action).getInputResultName(); 65 } 66 67 //获取执行的action方法上的@InputConfig注解 68 InputConfig annotation = action.getClass().getMethod(invocation.getProxy().getMethod(), EMPTY_CLASS_ARRAY).getAnnotation(InputConfig.class); 69 //如果确实加了这个注解的话 70 if (annotation != null) { 71 72 if (!annotation.methodName().equals("")) { 73 //调用注解上配置的methodName指定的方法,执行这个方法,使用这个方法的返回值作为返回字串 74 Method method = action.getClass().getMethod(annotation.methodName()); 75 //使用这个方法的返回值作为返回字串,这个方法可以做一些事情动态生成返回字串 76 resultName = (String) method.invoke(action); 77 } else { 78 //或者使用resultName作为返回字符串 ,这个值是直接指定的一个字符串 79 resultName = annotation.resultName(); 80 } 81 } 82 83 //悲剧了,拦截器栈不往下走了,到此结束掉(虽然在默认的拦截器栈里这就是最后一个了) 84 return resultName; 85 } 86 } 87 88 //拦截器栈继续走 89 return invocation.invoke(); 90 } 91 92 }