StaticParametersInterceptor 該攔截器處於defaultStack第十三的位置,是用來把通過<param>標簽配置在struts2配置文件中為Action配置的靜態參數填裝到Action中如果Action實現了Parameterizable接口,還會把靜態參數封裝成一個Map直接傳遞給Action,這些靜態參數還會添加到request參數Map中除非該攔截器的merge屬性為false,該屬性值默認是為true的。如下就是一段靜態參數配置: [html] <action name="staticparams" class="com.xtayfjpk.action.StaticParametersAction"> <result>/WEB-INF/page/message.jsp</result> <param name="username">zhangjin</param> <param name="password">xtayfjpk</param> </action> 下面是該攔截器的intercept方法源碼: [java] <span style="font-family:Courier New; font-size:14px">@Override public String intercept(ActionInvocation invocation) throws Exception { ActionConfig config = invocation.getProxy().getConfig();//獲取Action配置 Object action = invocation.getAction();//獲取當前執行的Action final Map<String, String> parameters = config.getParams();//獲取當前Action的靜態參數Map,注意不是request請求參數Map //省略... // 如果Action實現了Parameterizable接口 if (action instanceof Parameterizable) { ((Parameterizable) action).setParams(parameters);//調用Action的setParams方法,直接設置到Action中 } //如果Action配置有靜態參數 if (parameters != null) { ActionContext ac = ActionContext.getContext();//獲取ActionContext對象 Map<String, Object> contextMap = ac.getContextMap();//獲取ActionContext對象內部的context Map對象,即OgnlContext對象 try { //省略... final ValueStack stack = ac.getValueStack();//獲取ValueStack //省略... for (Map.Entry<String, String> entry : parameters.entrySet()) {//迭代靜態參數Map Object val = entry.getValue();//獲取當前參數值 if (parse && val instanceof String) {//如果parse為true則要將參數值要作為一個表達式進行計算,parse默認為false val = TextParseUtil.translateVariables(val.toString(), stack);//將返回的值進行替換 } try {//將當前參數設置到值棧中 newStack.setValue(entry.getKey(), val); } catch (RuntimeException e) { //省略... } } //省略... if (merge)//是否需要合並,默認為true addParametersToContext(ac, parameters);//將靜態參數添加到ActionContext中 } finally { //省略... } } return invocation.invoke();//調用下一個攔截器 }</span> 上面的源代碼中省略了一些非重要代碼,如果要查看完整源碼請參看struts2自帶源碼。 實際上該方法的邏輯還是比較簡單的,就是把Action配置中的靜態參數填裝到Action中而已,這個是通過newStack.setValue(entry.getKey(), val);這句代碼實現的,因為Action一般是處理ValueStack棧頂,如果Action中有參數接收的話就把參數值賦給了Action。 如果該攔截器的merge(默認為true)屬性為true,則還會把靜態參數添加到ActionContext中,下面是addParametersToContext方法源碼: [java] <span style="font-family:Courier New; font-size:14px">protected void addParametersToContext(ActionContext ac, Map<String, ?> newParams) { Map<String, Object> previousParams = ac.getParameters();//獲取請求參數 Map<String, Object> combinedParams; if ( overwrite ) {//是否需要對請求參數進行覆蓋 if (previousParams != null) { combinedParams = new TreeMap<String, Object>(previousParams);//這裡放的是previousParams請求參數 } else { combinedParams = new TreeMap<String, Object>(); } if ( newParams != null) { combinedParams.putAll(newParams);//再放靜態參數,如果有key相同,則請求參數覆蓋了靜態參數,就相當於沒有覆蓋請求參數 } } else { if (newParams != null) { combinedParams = new TreeMap<String, Object>(newParams);//先存放靜態參數 } else { combinedParams = new TreeMap<String, Object>(); } if ( previousParams != null) { combinedParams.putAll(previousParams);//再放請求參數,如果有key相同,則靜態參數覆蓋了請求參數 } } //將處理過後的參數設置到ActionContext中 ac.setParameters(combinedParams); }</span> 通過上面的方法完成了將靜態參數添加到ActionContext中,到這裡該攔截器邏輯就講解完畢了,最後調用invocation.invoke();調用下一個攔截器......