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);
取值:
<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的更多相关文章
- Nginx学习笔记(五) 源码分析&内存模块&内存对齐
		
Nginx源码分析&内存模块 今天总结了下C语言的内存分配问题,那么就看看Nginx的内存分配相关模型的具体实现.还有内存对齐的内容~~不懂的可以看看~~ src/os/unix/Ngx_al ...
 - Nginx学习笔记(四) 源码分析&socket/UDP/shmem
		
源码分析 在茫茫的源码中,看到了几个好像挺熟悉的名字(socket/UDP/shmem).那就来看看这个文件吧!从简单的开始~~~ src/os/unix/Ngx_socket.h&Ngx_s ...
 - Nginx学习笔记(六) 源码分析&启动过程
		
Nginx的启动过程 主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程. 涉及到的基本函数 源码: /* * ...
 - 五毛的cocos2d-x学习笔记02-基本项目源码分析
		
class AppDelegate : private cocos2d::Application private表示私有继承,cocs2d是一个命名空间.私有继承下,Application类中的pri ...
 - Bootstrap学习笔记上(带源码)
		
阅读目录 排版 表单 网格系统 菜单.按钮 做好笔记方便日后查阅o(╯□╰)o bootstrap简介: ☑ 简单灵活可用于架构流行的用户界面和交互接口的html.css.javascript工具集 ...
 - Redis学习之zskiplist跳跃表源码分析
		
跳跃表的定义 跳跃表是一种有序数据结构,它通过在每个结点中维持多个指向其他结点的指针,从而达到快速访问其他结点的目的 跳跃表的结构 关于跳跃表的学习请参考:https://www.jianshu.co ...
 - Java显式锁学习总结之六:Condition源码分析
		
概述 先来回顾一下java中的等待/通知机制 我们有时会遇到这样的场景:线程A执行到某个点的时候,因为某个条件condition不满足,需要线程A暂停:等到线程B修改了条件condition,使con ...
 - Python学习---Django的request.post源码分析
		
request.post源码分析: 可以看到传递json后会帮我们dumps处理一次最后一字节形式传递过去
 - Java显式锁学习总结之五:ReentrantReadWriteLock源码分析
		
概述 我们在介绍AbstractQueuedSynchronizer的时候介绍过,AQS支持独占式同步状态获取/释放.共享式同步状态获取/释放两种模式,对应的典型应用分别是ReentrantLock和 ...
 - 大数据学习笔记——HDFS写入过程源码分析(2)
		
HDFS写入过程注释解读 & 源码分析 此篇博客承接上一篇未讲完的内容,将会着重分析一下在Namenode获取到元数据后,具体是如何向datanode节点写入真实的数据的 1. 框架图展示 在 ...
 
随机推荐
- Python之路【第二十四篇】:Python学习路径及练手项目合集
			
Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...
 - xml_02
			
1.xml 2.对于XML文档的约束 |-DTD <!DOCTYPE 根元素 [ <!ELEMENT 元素名 (xx)> <!ATTLIS ...
 - java 从String中匹配数字,并提取数字
			
方法如下: private List<FieldList> GetTmpFieldsList(List<String> FieldsList,String tmptableNa ...
 - cmd命令积累
			
dir:展示所有目录 cd fileName:进入下一个目录 cd .. :返回上一层目录 cd\:返回根目录
 - 获取API返回值
			
//$return=getApiResult($url); // if ($return==200){ // //..... // } function getApiResult($url){ if( ...
 - Visual C++ 打印编程技术-编程基础
			
背景: windows产生前,操作系统(如DOS等)都不提供支持图像处理的打印机驱动程序,使得程序员为打印出图像,不得不针对使用的打印机 自己编写设备驱动程序,导致了大量的.不必要的重复开发. 随着w ...
 - caffe源码阅读(2)-Layer
			
神经网络是由层组成的,深度神经网络就是层数多了.layer对应神经网络的层.数据以Blob的形式,在不同的layer之间流动.caffe定义的神经网络已protobuf形式定义.例如: layer { ...
 - 【实习记】2014-08-27堆排序理解总结+使用typedef指代函数指针
			
过程记录 4个月前C语言版的七大排序算法实践让我在写C++版时轻车熟路.特别是冒泡,插入,希尔,选择这四种排序不用调试即运行成功.输出的效果与C语言做的版本完全一样,其中令我印象深刻的是,co ...
 - Google Web Designer 测试
			
这东东完全就是一个flash啊,简单测试,感觉就是个做HTML5动画的..不过暂时是beta版的, 官方安装版的半天打不开,这边有个绿色版的,需要的童鞋可以这里下载:百度网盘
 - SQLServer:定时作业
			
SQLServer:定时作业: 如果在SQL Server 里需要定时或者每隔一段时间执行某个存储过程或3200字符以内的SQL语句时,可以用管理-SQL Server代理-作业来实现 也快可以定时备 ...