zoukankan      html  css  js  c++  java
  • OA学习笔记-010-Struts部分源码分析、Intercepter、ModelDriver、OGNL、EL

    一、分析

    二、

    1.OGNL

    在访问action前,要经过各种intercepter,其中ParameterFilterInterceptor会把各咱参数放到ValueStack里,从而使OGNL可以访问这些参数,而ValueStack里包含对象stack和map

    (1)map

    赋值:ActionContext.getContext().put("roleList", roleList);

    取值:在jsp中通过ognl取<s:iterator value="#roleList">或<s:iterator value="%{#roleList}">

    注:因为struts标签默认使用ognl表达式,所以可以省略“%{}”,而“#”是表示从map中取值,不会去对象栈中去取

    (2)对象stack

    压栈:ActionContext.getContext().getValueStack().push(role);

    取值:

     1 <table cellpadding="0" cellspacing="0" class="mainForm">
     2                     <tr>
     3                         <td width="100">岗位名称</td>
     4                         <td><s:textfield name="name" cssClass="InputStyle" /> *</td>
     5                     </tr>
     6                     <tr>
     7                         <td>岗位说明</td>
     8                         <td><s:textarea name="description" cssClass="TextareaStyle"></s:textarea></td>
     9                     </tr>
    10                 </table>

    struts标签会自动去对象statck中找%{name}、%{description}

    2.El表达式

    若使用了struts框架,则request会被装饰类StrutsRequestWrapper代换,StrutsRequestWrapper包装了ServletRequest,也提供了访问valuestack的方法,所以使El表达式可以访问request中的值及访问valuestack,

    在jsp中写${name},此时的取值顺序是(1)先以request中取,若取不到就到valuestack取,源码如下:

      1 /*
      2  * $Id$
      3  *
      4  * Licensed to the Apache Software Foundation (ASF) under one
      5  * or more contributor license agreements.  See the NOTICE file
      6  * distributed with this work for additional information
      7  * regarding copyright ownership.  The ASF licenses this file
      8  * to you under the Apache License, Version 2.0 (the
      9  * "License"); you may not use this file except in compliance
     10  * with the License.  You may obtain a copy of the License at
     11  *
     12  *  http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing,
     15  * software distributed under the License is distributed on an
     16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     17  * KIND, either express or implied.  See the License for the
     18  * specific language governing permissions and limitations
     19  * under the License.
     20  */
     21 
     22 package org.apache.struts2.dispatcher;
     23 
     24 import com.opensymphony.xwork2.ActionContext;
     25 import com.opensymphony.xwork2.util.ValueStack;
     26 
     27 import javax.servlet.http.HttpServletRequest;
     28 import javax.servlet.http.HttpServletRequestWrapper;
     29 
     30 import static org.apache.commons.lang3.BooleanUtils.isTrue;
     31 
     32 /**
     33  * <!-- START SNIPPET: javadoc -->
     34  *
     35  * All Struts requests are wrapped with this class, which provides simple JSTL accessibility. This is because JSTL
     36  * works with request attributes, so this class delegates to the value stack except for a few cases where required to
     37  * prevent infinite loops. Namely, we don't let any attribute name with "#" in it delegate out to the value stack, as it
     38  * could potentially cause an infinite loop. For example, an infinite loop would take place if you called:
     39  * request.getAttribute("#attr.foo").
     40  *
     41  * <!-- END SNIPPET: javadoc -->
     42  *
     43  */
     44 public class StrutsRequestWrapper extends HttpServletRequestWrapper {
     45 
     46     private static final String REQUEST_WRAPPER_GET_ATTRIBUTE = "__requestWrapper.getAttribute";
     47     private final boolean disableRequestAttributeValueStackLookup;
     48 
     49     /**
     50      * The constructor
     51      * @param req The request
     52      */
     53     public StrutsRequestWrapper(HttpServletRequest req) {
     54         this(req, false);
     55     }
     56 
     57     /**
     58      * The constructor
     59      * @param req The request
     60      * @param disableRequestAttributeValueStackLookup flag for disabling request attribute value stack lookup (JSTL accessibility)
     61      */
     62     public StrutsRequestWrapper(HttpServletRequest req, boolean disableRequestAttributeValueStackLookup) {
     63         super(req);
     64         this.disableRequestAttributeValueStackLookup = disableRequestAttributeValueStackLookup;
     65     }
     66 
     67     /**
     68      * Gets the object, looking in the value stack if not found
     69      *
     70      * @param key The attribute key
     71      */
     72     public Object getAttribute(String key) {
     73         if (key == null) {
     74             throw new NullPointerException("You must specify a key value");
     75         }
     76 
     77         if (disableRequestAttributeValueStackLookup || key.startsWith("javax.servlet")) {
     78             // don't bother with the standard javax.servlet attributes, we can short-circuit this
     79             // see WW-953 and the forums post linked in that issue for more info
     80             return super.getAttribute(key);
     81         }
     82 
     83         ActionContext ctx = ActionContext.getContext();
     84         Object attribute = super.getAttribute(key);
     85 
     86         if (ctx != null && attribute == null) {
     87             boolean alreadyIn = isTrue((Boolean) ctx.get(REQUEST_WRAPPER_GET_ATTRIBUTE));
     88 
     89             // note: we don't let # come through or else a request for
     90             // #attr.foo or #request.foo could cause an endless loop
     91             if (!alreadyIn && !key.contains("#")) {
     92                 try {
     93                     // If not found, then try the ValueStack
     94                     ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.TRUE);
     95                     ValueStack stack = ctx.getValueStack();
     96                     if (stack != null) {
     97                         attribute = stack.findValue(key);
     98                     }
     99                 } finally {
    100                     ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.FALSE);
    101                 }
    102             }
    103         }
    104         return attribute;
    105     }
    106 }

    例如:

    1         <s:iterator value="#roleList">
    2             ${id},
    3             ${name},
    4             ${description}, 
    5             <s:a action="role_delete?id=%{id}" onclick="return confirm('确定要删除吗?')">删除</s:a>,
    6             <s:a action="role_editUI?id=%{id}">修改</s:a>
    7             <br/>
    8         </s:iterator>

    分析:s:iterator每次循环都会把当前对象压栈,循环结束就弹栈,${id}的访问顺序时先到对象栈里找,再到map里找,所以肯定可以找到

    3.ModelDriven

    ModelDriven的原理是,访问action前,ModelDrivenInterceptor会把model压到对象栈里,从而页面提交的比如id,name等字段会优先封闭到model里

    源码如下:

     1  @Override
     2     public String intercept(ActionInvocation invocation) throws Exception {
     3         Object action = invocation.getAction();
     4 
     5         if (action instanceof ModelDriven) {
     6             ModelDriven modelDriven = (ModelDriven) action;
     7             ValueStack stack = invocation.getStack();
     8             Object model = modelDriven.getModel();
     9             if (model !=  null) {
    10                 stack.push(model);
    11             }
    12             if (refreshModelBeforeResult) {
    13                 invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
    14             }
    15         }
    16         return invocation.invoke();
    17     }

    用法如:

    1         <s:form action="role_add">
    2             <s:textfield name="name"></s:textfield>
    3             <s:textarea name="description"></s:textarea>
    4             <s:submit value="提交"></s:submit>
    5         </s:form>

    一提交,字段会自动封装到role里去,因为RoleAction实现了ModelDriven

     1  @Override
     2     public String intercept(ActionInvocation invocation) throws Exception {
     3         Object action = invocation.getAction();
     4 
     5         if (action instanceof ModelDriven) {
     6             ModelDriven modelDriven = (ModelDriven) action;
     7             ValueStack stack = invocation.getStack();
     8             Object model = modelDriven.getModel();
     9             if (model !=  null) {
    10                 stack.push(model);
    11             }
    12             if (refreshModelBeforeResult) {
    13                 invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
    14             }
    15         }
    16         return invocation.invoke();
    17     }
  • 相关阅读:
    Python之字典
    Python之模块
    Python之字符串格式化
    结束循环
    循环
    C语言static和局部变量
    C static extern和全局变量
    extern static和函数
    C语言typedef
    C语言之文件包含
  • 原文地址:https://www.cnblogs.com/shamgod/p/5227247.html
Copyright © 2011-2022 走看看