Method类和cglib有鲜为人知的一腿?
请看我另一篇帖子http://topic.csdn.net/u/20100531/00/0fb8eeb7-e193-4e6f-9399-ef2aa0742d6b.html?300891006
经过我长达半天的追踪代码,发现了问题的所在,顺便给出这个帖子的解决方法:
问题就出在struts2中的chain拦截器中。当页面中使用了struts2标签中的<s:action>标签,或者其他显示返回chain结果时,在chain拦截器中,边会对一个上一个action的属性进行copy,而copy的实现是调用com.opensymphony.xwork2.ognl.OgnlUtil 类中的copy方法完成的,最终问题就是在这个方法中,请看代码:
public void copy(Object from, Object to, Map<String, Object> context, Collection<String> exclusions, Collection<String> inclusions) { if (from == null || to == null) { LOG.warn("Attempting to copy from or to a null source. This is illegal and is bein skipped. This may be due to an error in an OGNL expression, action chaining, or some other event."); return; } TypeConverter conv = getTypeConverterFromContext(context); Map contextFrom = Ognl.createDefaultContext(from); Ognl.setTypeConverter(contextFrom, conv); Map contextTo = Ognl.createDefaultContext(to); Ognl.setTypeConverter(contextTo, conv); PropertyDescriptor[] fromPds; PropertyDescriptor[] toPds; try { fromPds = getPropertyDescriptors(from); toPds = getPropertyDescriptors(to); } catch (IntrospectionException e) { LOG.error("An error occured", e); return; } Map<String, PropertyDescriptor> toPdHash = new HashMap<String, PropertyDescriptor>(); for (PropertyDescriptor toPd : toPds) { toPdHash.put(toPd.getName(), toPd); } for (PropertyDescriptor fromPd : fromPds) { //修改部分 begin if("targetSource".equals(fromPd.getName()) || "callback".equals(fromPd.getName()) || "callbacks".equals(fromPd.getName())){ continue; } //修改部分 end if (fromPd.getReadMethod() != null) { boolean copy = true; if (exclusions != null && exclusions.contains(fromPd.getName())) { copy = false; } else if (inclusions != null && !inclusions.contains(fromPd.getName())) { copy = false; } if (copy == true) { PropertyDescriptor toPd = toPdHash.get(fromPd.getName()); if ((toPd != null) && (toPd.getWriteMethod() != null)) { try { Object expr = compile(fromPd.getName()); Object value = Ognl.getValue(expr, contextFrom, from); Ognl.setValue(expr, contextTo, to, value); } catch (OgnlException e) { // ignore, this is OK } } } } } }
[解决办法]
实际上,出现了proxy是没有使用cglib的状态,action中实现了接口,对这个接口实现了proxy才会产生proxy的东西。如果是cglib产生了作用,生成的类名应该是UserXXXX$$CGLIB$enhance$$这样的。
[解决办法]