一、分析

二、

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);

取值:

 <table cellpadding="0" cellspacing="0" class="mainForm">
<tr>
<td width="100">岗位名称</td>
<td><s:textfield name="name" cssClass="InputStyle" /> *</td>
</tr>
<tr>
<td>岗位说明</td>
<td><s:textarea name="description" cssClass="TextareaStyle"></s:textarea></td>
</tr>
</table>

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

2.El表达式

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

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

 /*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ package org.apache.struts2.dispatcher; import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; import static org.apache.commons.lang3.BooleanUtils.isTrue; /**
* <!-- START SNIPPET: javadoc -->
*
* All Struts requests are wrapped with this class, which provides simple JSTL accessibility. This is because JSTL
* works with request attributes, so this class delegates to the value stack except for a few cases where required to
* prevent infinite loops. Namely, we don't let any attribute name with "#" in it delegate out to the value stack, as it
* could potentially cause an infinite loop. For example, an infinite loop would take place if you called:
* request.getAttribute("#attr.foo").
*
* <!-- END SNIPPET: javadoc -->
*
*/
public class StrutsRequestWrapper extends HttpServletRequestWrapper { private static final String REQUEST_WRAPPER_GET_ATTRIBUTE = "__requestWrapper.getAttribute";
private final boolean disableRequestAttributeValueStackLookup; /**
* The constructor
* @param req The request
*/
public StrutsRequestWrapper(HttpServletRequest req) {
this(req, false);
} /**
* The constructor
* @param req The request
* @param disableRequestAttributeValueStackLookup flag for disabling request attribute value stack lookup (JSTL accessibility)
*/
public StrutsRequestWrapper(HttpServletRequest req, boolean disableRequestAttributeValueStackLookup) {
super(req);
this.disableRequestAttributeValueStackLookup = disableRequestAttributeValueStackLookup;
} /**
* Gets the object, looking in the value stack if not found
*
* @param key The attribute key
*/
public Object getAttribute(String key) {
if (key == null) {
throw new NullPointerException("You must specify a key value");
} if (disableRequestAttributeValueStackLookup || key.startsWith("javax.servlet")) {
// don't bother with the standard javax.servlet attributes, we can short-circuit this
// see WW-953 and the forums post linked in that issue for more info
return super.getAttribute(key);
} ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(key); if (ctx != null && attribute == null) {
boolean alreadyIn = isTrue((Boolean) ctx.get(REQUEST_WRAPPER_GET_ATTRIBUTE)); // note: we don't let # come through or else a request for
// #attr.foo or #request.foo could cause an endless loop
if (!alreadyIn && !key.contains("#")) {
try {
// If not found, then try the ValueStack
ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.TRUE);
ValueStack stack = ctx.getValueStack();
if (stack != null) {
attribute = stack.findValue(key);
}
} finally {
ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.FALSE);
}
}
}
return attribute;
}
}

例如:

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

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

3.ModelDriven

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

源码如下:

  @Override
public String intercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction(); if (action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven) action;
ValueStack stack = invocation.getStack();
Object model = modelDriven.getModel();
if (model != null) {
stack.push(model);
}
if (refreshModelBeforeResult) {
invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
}
}
return invocation.invoke();
}

用法如:

         <s:form action="role_add">
<s:textfield name="name"></s:textfield>
<s:textarea name="description"></s:textarea>
<s:submit value="提交"></s:submit>
</s:form>

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

  @Override
public String intercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction(); if (action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven) action;
ValueStack stack = invocation.getStack();
Object model = modelDriven.getModel();
if (model != null) {
stack.push(model);
}
if (refreshModelBeforeResult) {
invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
}
}
return invocation.invoke();
}

OA学习笔记-010-Struts部分源码分析、Intercepter、ModelDriver、OGNL、EL的更多相关文章

  1. Nginx学习笔记(五) 源码分析&内存模块&内存对齐

    Nginx源码分析&内存模块 今天总结了下C语言的内存分配问题,那么就看看Nginx的内存分配相关模型的具体实现.还有内存对齐的内容~~不懂的可以看看~~ src/os/unix/Ngx_al ...

  2. Nginx学习笔记(四) 源码分析&socket/UDP/shmem

    源码分析 在茫茫的源码中,看到了几个好像挺熟悉的名字(socket/UDP/shmem).那就来看看这个文件吧!从简单的开始~~~ src/os/unix/Ngx_socket.h&Ngx_s ...

  3. Nginx学习笔记(六) 源码分析&启动过程

    Nginx的启动过程 主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程. 涉及到的基本函数 源码: /* * ...

  4. 五毛的cocos2d-x学习笔记02-基本项目源码分析

    class AppDelegate : private cocos2d::Application private表示私有继承,cocs2d是一个命名空间.私有继承下,Application类中的pri ...

  5. Bootstrap学习笔记上(带源码)

    阅读目录 排版 表单 网格系统 菜单.按钮 做好笔记方便日后查阅o(╯□╰)o bootstrap简介: ☑  简单灵活可用于架构流行的用户界面和交互接口的html.css.javascript工具集 ...

  6. Redis学习之zskiplist跳跃表源码分析

    跳跃表的定义 跳跃表是一种有序数据结构,它通过在每个结点中维持多个指向其他结点的指针,从而达到快速访问其他结点的目的 跳跃表的结构 关于跳跃表的学习请参考:https://www.jianshu.co ...

  7. Java显式锁学习总结之六:Condition源码分析

    概述 先来回顾一下java中的等待/通知机制 我们有时会遇到这样的场景:线程A执行到某个点的时候,因为某个条件condition不满足,需要线程A暂停:等到线程B修改了条件condition,使con ...

  8. Python学习---Django的request.post源码分析

    request.post源码分析: 可以看到传递json后会帮我们dumps处理一次最后一字节形式传递过去

  9. Java显式锁学习总结之五:ReentrantReadWriteLock源码分析

    概述 我们在介绍AbstractQueuedSynchronizer的时候介绍过,AQS支持独占式同步状态获取/释放.共享式同步状态获取/释放两种模式,对应的典型应用分别是ReentrantLock和 ...

  10. 大数据学习笔记——HDFS写入过程源码分析(2)

    HDFS写入过程注释解读 & 源码分析 此篇博客承接上一篇未讲完的内容,将会着重分析一下在Namenode获取到元数据后,具体是如何向datanode节点写入真实的数据的 1. 框架图展示 在 ...

随机推荐

  1. jquery处理textarea中的手动换行

    textarea的手动换行会产生换行标志,但这个标志存在却看不到,存入数据库中后读出来显示在页面上却不会换行,如何处理呢? 网上众说纷纭,经过测试用 textarea的内容.replace(/\n/g ...

  2. Java反序列化

    一.序列化和反序列化的概念       把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬 ...

  3. 四、使用Maven和使用Eclipse构建javaWeb项目

    环境前边已经搭建过了,我们就再弄了. 1.使用Maven构建javaWeb项目 (1).键入以下命令: $ mvn archetype:generate -DgroupId=com.holytax.w ...

  4. ORACLE 11g R2数据库安装硬件环境要求

    物理内存要求:最小1G,在windows7,windows8,windows8.1上最小2G. 虚拟内存(或分页空间)容量要求: Available RAM Swap Space Required B ...

  5. Oracle 11g之创建和管理表练习

    创建表: SQL> create table name (empno number(4), ename VARCHAR2(10)); 查看表结构: desc name; SQL> desc ...

  6. 数据操作So easy-LINQ解析

    1.LINQ是什么? LINQ是Language Integrated Query的缩写,即“语言集成查询”的意思.LINQ的提出就是为了提供一种跨越各种数据源的统一的查询方式,它主要包含4个组件-- ...

  7. Myeclipse下不用dom4j等解析xml文档

  8. 00_ForTest

    -----该页是爬虫的测试页请忽略------- 1234545@qq.comadasdsdasdsad阿打算多少其热情为 asdasdasdasd4w5wsdvv啊实打实大 啊实打实大asdasda ...

  9. [工具]toolbox_graph基本操作

    toolbox_graph提供了对3D模型的一些操作.MATLAB代码源自:http://www.mathworks.com/matlabcentral/fileexchange/5355-toolb ...

  10. leetcode problem 10 Regular Expression Matching(动态规划)

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...