Ognl的扩展点:
http://java12345678.iteye.com/blog/2031790
类OgnlValueStack 是struts2对Ognl的封装,提供了表达式取值或赋值方法,并不像ognl那样需要在方法参数中传递context,root 对象,因为context 、root对象已封状在OgnlValueStack 内部
Struts 对Ognl的封装,提供了setValue、set、setParameter等方法通过表达式赋值,findValue,findString 等方法取值。
构建器调用setRoot方法构建OgnlValueStack对象,并生成Ognl需要的相关对象:
protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot, boolean allowStaticMethodAccess) { this.root = compoundRoot; this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess); this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess); context.put(VALUE_STACK, this); Ognl.setClassResolver(context, accessor); ((OgnlContext) context).setTraceEvaluations(false); ((OgnlContext) context).setKeepLastEvaluation(false); }
1.ognl上下文:Map<String,Object> contex
this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess);
2. ognl的root对象:CompoundRoot root=CompoundRoot :,表达式从中取值或赋值
3:MemeberAccess: ognl的成员是否可以访问(SecurityMemberAccess)
this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess);
4.ognl的ClassResolver(用于加载类)(CompoundRootAccessor)
Ognl.setClassResolver(context, CompoundRootAccessor);
5.ognl的TypeConverter 用于类型转换(new OgnlTypeConverterWrapper(XWorkConverter))
6.PropertyAccessor
由工厂ValueStackFactory生成实例时,注入Container时,调用OgnlRuntime.setPropertyAccessor
7.MethodAccessor
由工厂ValueStackFactory生成实例时,注入Container时,调用OgnlRuntime.setMethodAccessor
8.NullHandler
由工厂ValueStackFactory生成实例时,注入Container时,调用OgnlRuntime.setNullHandler
ValueStackFactory类的方法:
@Inject public void setContainer(Container container) throws ClassNotFoundException { Set<String> names = container.getInstanceNames(PropertyAccessor.class); for (String name : names) { Class cls = Class.forName(name); if (cls != null) { if (Map.class.isAssignableFrom(cls)) { PropertyAccessor acc = container.getInstance(PropertyAccessor.class, name); } OgnlRuntime.setPropertyAccessor(cls, container.getInstance(PropertyAccessor.class, name)); if (compoundRootAccessor == null && CompoundRoot.class.isAssignableFrom(cls)) { compoundRootAccessor = (CompoundRootAccessor) container.getInstance(PropertyAccessor.class, name); } } } names = container.getInstanceNames(MethodAccessor.class); for (String name : names) { Class cls = Class.forName(name); if (cls != null) { OgnlRuntime.setMethodAccessor(cls, container.getInstance(MethodAccessor.class, name)); } } names = container.getInstanceNames(NullHandler.class); for (String name : names) { Class cls = Class.forName(name); if (cls != null) { OgnlRuntime.setNullHandler(cls, new OgnlNullHandlerWrapper(container.getInstance(NullHandler.class, name))); } } if (compoundRootAccessor == null) { throw new IllegalStateException("Couldn't find the compound root accessor"); } this.container = container; } }
OgnlValueStack提供的findxxx方法,通过表达式取值,都会调用如下:
private Object tryFindValue(String expr) throws OgnlException { Object value; if (defaultType != null) { value = findValue(expr, defaultType); } else { value = getValueUsingOgnl(expr); if (value == null) {//在ognl中没有找到 value = findInContext(expr);//到上下文中查找 } } return value; } /** *使用Ognl获取表达式的值 参数contxt上下文,root对象 **/ private Object getValueUsingOgnl(String expr) throws OgnlException { try { return ognlUtil.getValue(expr, context, root); } finally { context.remove(THROW_EXCEPTION_ON_FAILURE); } } /** * ognlUtil类中的方法 * 使用Ognl获取表达式的值 */ public Object getValue(String name, Map<String, Object> context, Object root) throws OgnlException { return Ognl.getValue(compile(name, context), context, root); } /** *从上下文的Map对象中直接get */ private Object findInContext(String name) { return getContext().get(name); }
OgnlValueStack提供的setParameter和setValue方法,通过表达式赋值,都会调用如下:
相关推荐
- XWork的`OgnlValueStack`是表达式语言OGNL(Object-Graph Navigation Language)在Struts2中的实现,用于在Action和视图之间传递数据。 - 类型转换是XWork的一个重要特性,它可以自动将请求参数转换为Action字段...
使用OGNL表达式的一个关键原因是Struts2对HttpServletRequest进行了封装,创建了StrutsRequestWrapper类,这允许OGNL在不直接操作原始HTTP请求对象的情况下,仍能访问请求参数和其他特性,提高了代码的简洁性和可...
为了使EL表达式能够访问`ValueStack`中的数据,Struts2在`HttpServletRequest`的基础上封装了一个类——`StrutsRequestWrapper`。这个类重写了`getAttribute_r`方法,使其能够在没有找到相应属性时,尝试从`...
4. **Ognl(Object-Graph Navigation Language)**:Struts2内部使用OGNL作为表达式语言,用于在Action和视图之间传递数据。这使得视图能够灵活地访问Action对象的属性,反之亦然。 5. **Plug-in机制**:Struts2...
Xwork作为Struts2的核心组件之一,它的设计理念和技术实现对整个Struts2框架起着决定性的作用。Struts2是一个流行的Java Web开发框架,它采用了MVC(Model-View-Controller)架构模式来帮助开发者构建易于维护和扩展的...
1. **ValueStack内部结构**:`OgnlValueStack`是Struts2中用于存储和管理数据的关键组件。其内部包含了一个`CompoundRoot`对象,用于存放当前的Action对象,以及一个`Map, Object>`对象,用于存储各种上下文信息,如...
`com.opensymphony.xwork2.ognl`包下的OgnlValueStack和OgnlUtil等类,是Ognl在xwork2中的具体实现。 在异常处理方面,xwork2提供了ActionError和ActionException等类,用于处理和展示应用程序运行时出现的错误。...