国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

關于struts2的modelDriven

2019-11-14 21:41:42
字體:
來源:轉載
供稿:網友
關于struts2的modelDriven

今天做畢業設計,前臺往后臺賦值,習慣性的用了modelDriven。但是剛寫完就奇怪它的機理是怎樣的,它怎么知道我前臺傳的參是哪個Model的屬性(之前用servlet都是手動),于是手賤的ctrl點進去,簡單了解了一下


之前記得要使用modelDriven必須使用modelDriven的攔截器,但是我沒加這個攔截器也實現了功能,看默認攔截器defaultStack原來所謂的默認攔截器就是一系列攔截器的集合

看modelDriven的源碼可以看到

 1     @Override 2  3 public String intercept(ActionInvocation invocation) throws Exception { 4  5 //獲取 Action 對象: EmployeeAction 對象, 此時該 Action 已經實現了 ModelDriven 接口 6  7     //public class EmployeeAction implements RequestAware, ModelDriven<Employee> 8  9         Object action = invocation.getAction();10 11 //判斷 action 是否是 ModelDriven 的實例12 13         if (action instanceof ModelDriven) {14 15 //強制轉換為 ModelDriven 類型16 17             ModelDriven modelDriven = (ModelDriven) action;18 19 //獲取值棧20 21             ValueStack stack = invocation.getStack();22 23 //調用 ModelDriven 接口的 getModel() 方法24 25             //即調用 EmployeeAction 的 getModel() 方法26 27             /*28 29             public Employee getModel() {30 31               employee = new Employee();32 33               return employee;34 35            }36 37             */38 39             Object model = modelDriven.getModel();40 41             if (model !=  null) {42 43 //把 getModel() 方法的返回值壓入到值棧的棧頂. 實際壓入的是 EmployeeAction 的 employee 成員變量44 45               stack.push(model);46 47             }48 49             if (refreshModelBeforeResult) {50 51                 invocation.addPReResultListener(new RefreshModelBeforeResult(modelDriven, model));52 53             }54 55         }56 57         return invocation.invoke();

發現它什么也沒實現,就是modelDriven接口,如果實現了就調用了它的getModel方法,然后把得到的壓入棧頂。沒有賦值操作

那么流程圖應該是這樣:

那么setName()賦值操作是誰做的?ParametersInterceptor

那么結論是:

1)ModelDrivenInterceptor只是將實現了ModelDriven的action的model放入值棧而已,所以你才可以直接使用<input type="text" name="type" />傳值。2)如果action沒有實現此接口,那么配置ModelDrivenInterceptor沒有任何意義3)ModelDrivenInterceptor并不負責注入值,賦值的是ParametersInterceptor


如果還要深究的話

ParametersInterceptor攔截器繼承自MethodFilterInterceptor,其主要功能是把ActionContext中的請求參數設置到ValueStack中,如果棧頂是當前Action則把請求參數設置到了Action中,如果棧頂是一個model(Action實現了ModelDriven接口)則把參數設置到了model中。

ParametersInterceptor攔截器主要源碼:

 1 @Override   2 public String doIntercept(ActionInvocation invocation) throws Exception {   3     Object action = invocation.getAction();//獲取當前執行的Action對象   4     if (!(action instanceof NoParameters)) {//判斷Action是否實現了NoParameters接口,實現該接口表示該Action沒有任何請求參數   5         ActionContext ac = invocation.getInvocationContext();//獲取ActionContext對象   6         final Map<String, Object> parameters = retrieveParameters(ac);//獲取請求參數Map   7         //省略...   8         if (parameters != null) {//如果請求參數不為null   9             Map<String, Object> contextMap = ac.getContextMap();//獲取ActionContext內部的context Map,即OgnlContext對象  10             try {  11                 //省略...  12                 ValueStack stack = ac.getValueStack();//獲取值棧  13                 setParameters(action, stack, parameters);//為值棧設置參數  14             } finally {  15                 //省略...  16             }  17         }  18     }  19     return invocation.invoke();//調用下一個攔截器  20 }  

可以知道為什么要實現自動賦值,只需要實現modelDriven接口就行了

其中最重要邏輯代碼是setParometers()方法

 1 protected void setParameters(Object action, ValueStack stack, final Map<String, Object> parameters) {   2     ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware)   3             ? (ParameterNameAware) action : null;//判斷Action有無實現ParameterNameAware接口   4    5     Map<String, Object> params;   6     Map<String, Object> acceptableParameters;//合法參數集合   7     //判斷參數設置是否有序,ordered默認為false,即無序   8     if (ordered) {   9         params = new TreeMap<String, Object>(getOrderedComparator());//如果有序則要獲取比較器  10         acceptableParameters = new TreeMap<String, Object>(getOrderedComparator());  11         params.putAll(parameters);  12     } else {  13         params = new TreeMap<String, Object>(parameters);  14         acceptableParameters = new TreeMap<String, Object>();  15     }  16     //迭代請求參數  17     for (Map.Entry<String, Object> entry : params.entrySet()) {  18         String name = entry.getKey();  19         //判斷參數是否合法,如果Action實現了ParameterNameAware則acceptableName(name)返回true且parameterNameAware.acceptableParameterName(name)  20         //也返回true該參數才是合法的;如果Action沒有實現ParameterNameAware則參數是否合法由acceptableName(name)方法決定  21         boolean acceptableName = acceptableName(name)  && (parameterNameAware == null  || parameterNameAware.acceptableParameterName(name));  22         //如果參數合法  23         if (acceptableName) {  24             acceptableParameters.put(name, entry.getValue());//把合法參數添加到合法參數集合中  25         }  26     }  27   28     ValueStack newStack = valueStackFactory.createValueStack(stack);  29     //省略...  30     for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) {//迭代合法參數  31         String name = entry.getKey();//參數名  32         Object value = entry.getValue();//參數值  33         try {  34             newStack.setValue(name, value);//將該參數設置到ValueStack中  35         } catch (RuntimeException e) {  36             //省略...  37         }  38     }  39     //省略...  40     //看該方法的名稱是將合法參數添加到ActionContext中,但在該攔截器中,該方法為空實現,無任何代碼  41     //該方法被聲明為protected,即子類可以覆蓋該方法以改變行為  42     addParametersToContext(ActionContext.getContext(), acceptableParameters);  43 }  

先判斷提交過來的參數是否合法,因為提交過來的參數會影響到值棧所以struts2要對提交過來的參數進行合法性檢查,以防止惡意用戶的攻擊,凡是請求參數中表達式中含有等號(=),逗號(,),#號(#)的都是非法表達式

至于怎么判斷是否合法,我已經沒興趣了,知道是acceptableName(name)方法決定的。


了解了這么多感覺用的更隨心所欲了。急需做無聊的畢業設計



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 旺苍县| 五大连池市| 临湘市| 漳浦县| 伽师县| 三亚市| 龙江县| 阳东县| 神木县| 搜索| 松原市| 泰顺县| 周宁县| 彭州市| 长宁县| 昭平县| 五大连池市| 庐江县| 明水县| 巧家县| 依安县| 攀枝花市| 博兴县| 杂多县| 莱州市| 永昌县| 同仁县| 梁平县| 迁西县| 阿拉善盟| 仪陇县| 凤翔县| 朝阳市| 宁蒗| 炉霍县| 宁夏| 河源市| 夏河县| 河东区| 河东区| 蒙自县|