Ognl 中NullHandler
1.用于方法调用返回值为null时的处理,可以生成一个对象代替方法返回值。
2.用于属性取值时返回值为null时的处理,可以生成一个对象为该属性赋值再返回。
举例:
如前台页面提交user.name=yanlei,但Action中的user对象为null,则可以新建user对象,赋给Action,再把user对象的name属性赋值=yanlei.
Struts 加载扩展的NullHandler :
Struts 中在OgnlValueStackFactory中调用OgnlRuntime.setNullHandler(Class clazz, NullHandler 实例)方法来加载Struts中定义的NullHandlerAccessor。
在OgnlValueStackFactory 实例化之后,注入Containter时:
@Inject
public void setContainer(Container container) throws ClassNotFoundException {
//省略其它代码
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)));
}
}
this.container = container;
}
那么Container中的MethodAccessor类是从哪加载进来的呢??
是由Struts-default.xml中bean定义中加载的:
<bean type="com.opensymphony.xwork2.conversion.NullHandler" name="java.lang.Object" class="com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler" />
该NullHandler 非Ognl.NullHandler,Ognl不认识,所以需要接口适配器OgnlNullHandlerWrapper对其进行包装。
InstantiatingNullHandler 对nullMethodResult 直接返回null,没有处理。
nullPropertyValue方法:
如果允许新建属性对象:ReflectionContextState.isCreatingNullObjects(context)==true,则新建属性,并赋值给当前类,返回新建的属性对象。