首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

struts 2.2.1 中ActionChainResult的批改[CSDN迁移文章]

2012-10-08 
struts 2.2.1 中ActionChainResult的修改[CSDN迁移文章]@Overridepublic String intercept(ActionInvocati

struts 2.2.1 中ActionChainResult的修改[CSDN迁移文章]

@Override public String intercept(ActionInvocation invocation) throws Exception { ValueStack stack = invocation.getStack(); CompoundRoot root = stack.getRoot(); if (root.size() > 1) { List<CompoundRoot> list = new ArrayList<CompoundRoot>(root); list.remove(0); Collections.reverse(list); Map<String, Object> ctxMap = invocation.getInvocationContext().getContextMap(); Iterator<CompoundRoot> iterator = list.iterator(); int index = 1; // starts with 1, 0 has been removed while (iterator.hasNext()) { index = index + 1; Object o = iterator.next(); if (o != null) { if (!(o instanceof Unchainable)) {//拷贝属性值到将要执行的Action中 reflectionProvider.copy(o, invocation.getAction(), ctxMap, excludes, includes); } } else { LOG.warn("compound root element at index "+index+" is null"); } } }? @Override public String intercept(ActionInvocation invocation) throws Exception { ValueStack stack = invocation.getStack(); CompoundRoot root = stack.getRoot(); if (root.size() > 1) { List<CompoundRoot> list = new ArrayList<CompoundRoot>(root); list.remove(0); Collections.reverse(list); Map<String, Object> ctxMap = invocation.getInvocationContext().getContextMap(); Iterator<CompoundRoot> iterator = list.iterator(); int index = 1; // starts with 1, 0 has been removed while (iterator.hasNext()) { index = index + 1; Object o = iterator.next(); if (o != null) { if (!(o instanceof Unchainable)) {//拷贝属性值到将要执行的Action中 reflectionProvider.copy(o, invocation.getAction(), ctxMap, excludes, includes); } } else { LOG.warn("compound root element at index "+index+" is null"); } } }

对于这种方式的好处,我们或许已经默默的在使用了。还是前面提到的Action a和Action bar,若Action a和Action bar都有一个共同的属性叫common,并且都有get、set方法。那么在Action a中的一些处理后,属性common有了值,经过chain resultType时,Action bar的common会自动被赋值。如果你在升级到struts2.2.1后,发现一些请求返回了NullPointerException,那么很有可能是struts2.2.1对ChainingInterceptor的修改导致了这个问题。

以下是struts 2.2.1中的ChainingInterceptor源代码

public String intercept(ActionInvocation invocation) throws Exception { ValueStack stack = invocation.getStack(); CompoundRoot root = stack.getRoot(); if (root.size() > 1 && isChainResult(invocation)) { List<CompoundRoot> list = new ArrayList<CompoundRoot>(root); list.remove(0); Collections.reverse(list); Map<String, Object> ctxMap = invocation.getInvocationContext().getContextMap(); Iterator<CompoundRoot> iterator = list.iterator(); int index = 1; // starts with 1, 0 has been removed while (iterator.hasNext()) { index = index + 1; Object o = iterator.next(); if (o != null) { if (!(o instanceof Unchainable)) { reflectionProvider.copy(o, invocation.getAction(), ctxMap, excludes, includes); } } else { LOG.warn("compound root element at index " + index + " is null"); } } } return invocation.invoke(); }?

和前面的相比,if (root.size() > 1) 中对了一个判断isChainResult(invocation)。这个判断让我有些纳闷,因为根据我的一些跟踪,在ActionInvocation调用invoke()方法前,ActionInvocation中的result属性是null,所以这个if总是false。难道有什么其他设置能恢复原来类似功能吗?希望有高人解答。正是因为这个问题,若你还希望使用原来chain的拷贝功能,你需要删除isChainResult(invocation)这个判断。

以下是一个很有趣的实验,首先我们看核心的struts.xml配置信息:

<package name="default" namespace="/" extends="struts-default"> <!-- <default-action-ref name="index" /> --> <action name="index"> <result>index.jsp</result> </action> <action name="chainSrc" name="code" style="display: none;"> <package name="default" namespace="/" extends="struts-default"> <!-- <default-action-ref name="index" /> --> <action name="index"> <result>index.jsp</result> </action> <action name="chainSrc" name="code">import com.opensymphony.xwork2.ActionSupport;public class ChainSrcAction extends ActionSupport {private String p1;private String p2 = "chain";@Overridepublic String execute() throws Exception {System.out.println(ChainSrcAction.class+"p1="+p1);System.out.println(ChainSrcAction.class+"p2="+p2);return SUCCESS;}public String getP1() {return p1;}public void setP1(String p1) {this.p1 = p1;}public String getP2() {return p2;}}?

ChainDestAction的源代码:

import com.opensymphony.xwork2.ActionSupport;public class ChainDestAction extends ActionSupport {private String p1;private String p2 ;@Overridepublic String execute() throws Exception {System.out.println(ChainDestAction.class+"p1="+p1);System.out.println(ChainDestAction.class+"p2="+p2);return SUCCESS;}public String getP1() {return p1;}public void setP1(String p1) {this.p1 = p1;}public String getP2() {return p2;}public void setP2(String p2) {this.p2 = p2;}}?

在struts 2.2.1的环境下,在地址栏上输入"http://127.0.0.1/s221/chainSrc.action?p1=struts2.2.1"你将会得到以下答案:

class ChainSrcActionp1=struts2.2.1
class ChainSrcActionp2=chain
class ChainDestActionp1=struts2.2.1
class ChainDestActionp2=null

在struts 2.1.8的环境下,相同的访问你会得到答案:

class ChainSrcActionp1=struts2.2.1
class ChainSrcActionp2=chain
class ChainDestActionp1=struts2.2.1
class ChainDestActionp2=chain

如果你将ChainingInterceptor中的if (root.size() > 1 && isChainResult(invocation))改为if (root.size() > 1 ),你也可以得到struts 2.1.8的结果。对于熟悉p1,它始终都得到了赋值是因为还有ParametersInterceptor对它赋值。

热点排行