别名拦截器(action属性传递拦截器)
定义
摘自网络:该拦截器主要作用是将一个参数别名成为另一个参数,在不同的action之间相似的参数(但是不同名)扮演着胶水的角色。——action之间的参数传递拦截器
使用
sendAction:发送参数类
public class SendParamAction {
public String from;
public String execute() {
setFrom("msg msg msg!!!");
System.out.println("do the SendParamAction!");
return "success";
}
//get,set省略,必不可少
}
receiveAction:接收参数类
public class ReceiveParamAction {
public String to;
public String execute() {
System.out.println("do the ReceiveParamAction!");
ValueStack vs=ActionContext.getContext().getValueStack();
vs.set("key1", "value1");
System.out.println(vs.findValue("key1"));
Object map=(Object) vs.findValue("#{'key2' :'value2'}");
if(map instanceof Map){
System.out.println("is a map!");
System.out.println(((Map) map).get("key2"));
}
return "success";
}
//get,set省略..
}
struts-xx.xml配置:
<action name="send" class="com.company.strutstudy.web.action.core.SendParamAction">
<result name="success" type="chain">receive.action</result>
</action>
<action name="receive"
class="com.company.strutstudy.web.action.core.ReceiveParamAction">
<interceptor-ref name="alias"></interceptor-ref>
<param name="key1">value1</param>
<param name="key2">value2</param>
<param name="aliases">#{'from' :'to'}</param>
<result name="success">/core/receive.jsp</result>
</action>
jsp页面:${to } 结果:msg msg msg!!!
源码阅读:
public class AliasInterceptor extends AbstractInterceptor {
private static final Log log = LogFactory.getLog(AliasInterceptor.class);
private static final String DEFAULT_ALIAS_KEY = "aliases";
protected String aliasesKey = DEFAULT_ALIAS_KEY;
public void setAliasesKey(String aliasesKey) {
this.aliasesKey = aliasesKey;
}
public String intercept(ActionInvocation invocation) throws Exception {
//Action的配置信息
ActionConfig config = invocation.getProxy().getConfig();
//Action的上下文
ActionContext ac = invocation.getInvocationContext();
//得到action的配置参数key:value形式
final Map parameters = config.getParams();
if (parameters.containsKey(aliasesKey)) {
String aliasExpression = (String) parameters.get(aliasesKey);
/*
* 得到值栈,这里的值栈非常关键
* 1.栈顶必定是该拦截器所拦截的action对象
* 2.栈顶下面的对象取决去action跳转方式
* -chain方式:有跳转之前的action对象
* -redirect方式:没有跳转之前的action对象
*/
ValueStack stack = ac.getValueStack();
//#{'someList' :'otherList'} 构建一map
Object obj = stack.findValue(aliasExpression);
//对于map进行迭代循环,复制拷贝的过程
if (obj != null && obj instanceof Map) {
// override
Map aliases = (Map) obj;
Iterator itr = aliases.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
String name = entry.getKey().toString();//someList
String alias = (String) entry.getValue();//otherList
Object value = stack.findValue(name);
if (null == value) {
// workaround
Map contextParameters = ac.getParameters();
if (null != contextParameters) {
value = contextParameters.get(name);
}
}
if (null != value) {
//对栈顶对象的alias所表示的属性名称进行set
//前提是action有set方法,否则set不进去
stack.setValue(alias, value);
}
}
} else {
log.debug("invalid alias expression:" + aliasesKey);
}
}
return invocation.invoke();
}
}
总结:
- chain方式的action属性传递
- 虽然chain方式不建议经常使用,但此拦截器从某种程度而言节省了裸用chain时的内存
- chain方式传递参数,我们可以通过request等对象进行set设置,get进行获取,相对于配置化的方式而言繁琐不少。
- 因此推荐此种方式进行传递。