root 对象
CompoundRoot, CompoundRoot扩展了ArrayList,具有容纳对象及后进先出类似“栈”的能力。
public class CompoundRoot extends ArrayList { public CompoundRoot() { } public CompoundRoot(List list) { super(list); } public CompoundRoot cutStack(int index) { return new CompoundRoot(subList(index, size())); } public Object peek() { return get(0); } public Object pop() { return remove(0); } public void push(Object o) { add(0, o); } }
(不明白为啥用0做栈顶呢?ArrayList 每次push 或remove 之后都需要重建数组)
CompoundRoot中元素的添加及提取:
OgnlValueStack提供的peek,pop,push 方法,从root中提取元素或添加元素:
- /**
- * @see com.opensymphony.xwork2.util.ValueStack#peek()
- */
- public Object peek() {
- return root.peek();
- }
- /**
- * @see com.opensymphony.xwork2.util.ValueStack#pop()
- */
- public Object pop() {
- return root.pop();
- }
- /**
- * @see com.opensymphony.xwork2.util.ValueStack#push(java.lang.Object)
- */
- public void push(Object o) {
- root.push(o);
- }
通过表达式对CompoundRoot中元素的访问
CompoundRootAccessor 实现了对 CompoundRoot 中元素以表达式方式的访问,
CompoundRootAccessor类扩展了ognl的PropertyAccessor,MethodAccessor,ClassResolver
Ognl中的root对象一般是一个javabean或Map,通过表达式中指定的属性名或key,就可以定位到属性对象
CompoundRoot 是一个ArrayList,对于表达式中指定的属性,是ArrayList中哪一个元素的属性呢? 这就需要遍历每一个元素,进行判断。
以表达式方式对CompoundRoot 中元素的属性赋值(setProperty):
对 CompoundRoot 遍历,遍历顺序由栈顶到栈底,遍历的每一个元素,都当做ognl的root对象,判断是否存在指定的属性,如果存在则对该root对象的属性赋值,遍历中下一个元素是Map,则直接使用put 方法存属性和名称,就不继续查找了:
for (Object o : root) {//CompoudRoot是ArrayList,遍历内部所有对象 if (o == null) { continue; } try { if (OgnlRuntime.hasSetProperty(ognlContext, o, name)) { OgnlRuntime.setProperty(ognlContext, o, name, value); //当前元素有name属性,则调用ognl进行赋值 return; } else if (o instanceof Map) { Map<Object, Object> map = (Map) o; try { map.put(name, value); return;//如果下一个元素是Map,则直接使用put方法存属性名和值 } catch (UnsupportedOperationException e) { // This is an unmodifiable Map, so move on to the next element in the stack } } }
以表达式方式对CompoundRoot 中元素的属性值的获值(getProperty):
对 CompoundRoot 遍历,遍历顺序由栈顶到栈底,遍历的每一个元素,都当做ognl的root对象,判断是否存在指定的属性,如果存在则获值属性值:
for (Object o : root) {//遍历 if (o == null) { continue; } try { if ((OgnlRuntime.hasGetProperty(ognlContext, o, name)) || ((o instanceof Map) && ((Map) o).containsKey(name))) { return OgnlRuntime.getProperty(ognlContext, o, name);//当前元素有该属性,则获取 } } catch (OgnlException e) { if (e.getReason() != null) { final String msg = "Caught an Ognl exception while getting property " + name; throw new XWorkException(msg, e); } } catch (IntrospectionException e) { // this is OK if this happens, we'll just keep trying the next } }
以表达式方式对CompoundRoot 中元素的方法调用(callMethod):
对 CompoundRoot 遍历,遍历顺序由栈顶到栈底,遍历的每一个元素,都当做ognl的root对象,对其调用指定的方法,如果返回值不为空,则说明正确,并返回方法返回值。
for (Object o : root) {//遍历 if (o == null) { continue; } Class clazz = o.getClass(); Class[] argTypes = getArgTypes(objects); MethodCall mc = null; if (argTypes != null) { mc = new MethodCall(clazz, name, argTypes); } if ((argTypes == null) || !invalidMethods.containsKey(mc)) { try { Object value = OgnlRuntime.callMethod((OgnlContext) context, o, name, name, objects); if (value != null) {//返回值不为空,该元素上有此方法并调用成功 return value; } } catch (OgnlException e) { // try the next one Throwable reason = e.getReason(); if (!context.containsKey(OgnlValueStack.THROW_EXCEPTION_ON_FAILURE) && (mc != null) && (reason != null) && (reason.getClass() == NoSuchMethodException.class)) { invalidMethods.put(mc, Boolean.TRUE); } else if (reason != null) { throw new MethodFailedException(o, name, e.getReason()); } } } }
对 CompoundRoot 指定位置元素的访问:
1.top.属性名 (top 栈顶元素)
2.[index].top CompoundRoot 中的第N个元素[index]会调用 CompoundRoot.cutStack从第indedx位置开始的元素组成新的 CompoundRoot,top是栈顶元素
相关推荐
使用OGNL表达式的一个关键原因是Struts2对HttpServletRequest进行了封装,创建了StrutsRequestWrapper类,这允许OGNL在不直接操作原始HTTP请求对象的情况下,仍能访问请求参数和其他特性,提高了代码的简洁性和可...
### OGNL表达式的理解和应用 ...通过上述介绍可以看出,OGNL作为一种强大的表达式语言,在Struts2框架中扮演着非常重要的角色,不仅可以方便地访问和操作对象属性,还能有效地处理复杂的业务逻辑。
4. **配置过滤器**:编辑`/Webroot/WEB-INF/web.xml`文件,添加Struts2的过滤器配置。 ```xml <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-...
- Struts2除了支持JSTL外,还内置了一个更加强大和灵活的表达式语言——OGNL,这使得数据操作更加简便。 #### 四、Struts2的优越性 - **开发前景**: Struts2是由Struts1和WebWork框架的开发团队共同开发的,具有...
6. **Ognl(Object-Graph Navigation Language)**:Struts 2使用Ognl作为默认表达式语言,用于在Action与视图之间传递数据。 7. **Plug-in体系结构**:Struts 2支持插件化开发,通过StrutsPrepareAndExecuteFilter...
根据提供的文件信息,我们可以归纳出以下关于Struts2中OGNL(Object-Graph Navigation Language)的知识点: ### 1. 引言与简介 OGNL 是一种强大的表达式语言,它允许开发人员通过简洁的语法来导航 Java 对象。...
例如,你可以创建一个`Employee`类来封装查询结果,然后将`List<Employee>`对象放入`ValueStack`,在JSP中使用OGNL表达式访问并展示数据。 以上就是使用Struts2连接MySQL并进行多表查询的基本步骤和关键知识点。...
Struts2的核心是ValueStack,它是OGNL(Object-Graph Navigation Language)表达式语言的数据上下文。在这个项目中,分页相关的数据(如总页数、当前页数据列表等)会被放入ValueStack,然后在JSP页面上通过OGNL...
- **ognl-2.7.3.jar**:对象图导航语言,用于访问和修改对象图。 - **freemarker-2.3.15.jar**:模板引擎,用于页面渲染。 - **commons-fileupload-1.2.1.jar**:文件上传组件。 - **commons-io-1.3.2.jar**:提供了...
实体Bean是ibatis与数据库交互的核心对象,用于封装数据。例如,这里定义了`Student`、`User`和`Page`三个实体Bean。 - **Student.java** ```java package com.vstsoft.model; import java.io.Serializable; ...