AliasInterceptor拦截器是Struts2默认拦截器中的第二个拦截器。它的作用是:给参数起一个别名,可用于在action链中以不同的名字共享同一个参数,也可用于把http请求参数以不同的名字映射到action里。也许你现在还有点疑惑,我们后面会给个例子程序。
配置
<action name="Student" class="Action.StudentAction"> <param name="aliases">#{'t_id':'s_id'}</param> <result> /Student/StudentAddSuccess.jsp </result> </action>
你只要关注<param name="aliases">#{'t_id':'s_id'}</param>。这就是设置别名共享同一个参数值。t_id为原名,s_id为别名。
下面以实现在action链中以不同的名字共享同一个参数为例
struts.xml:
<action name="Student" class="Action.StudentAction"> <param name="aliases">#{'t_id':'s_id'}</param> <result> /Student/StudentAddSuccess.jsp </result> </action> <action name="Teacher" class="Action.TeacherAction"> <result type="chain">Student</result> </action>
public class StudentAction extends ActionSupport{ private int s_id; public int getS_id() { return s_id; } public void setS_id(int sId) { s_id = sId; } public String Add(){ return SUCCESS; } public String Delete(){ return SUCCESS; } public String execute() { System.out.println(s_id); return SUCCESS; } }
public class TeacherAction extends ActionSupport { private int t_id; public int getT_id() { return t_id; } public void setT_id(int tId) { t_id = tId; } public String execute() { return SUCCESS; } }
/Student/StudentAddSuccess.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> </head> <body> Student Add Success!! <br> <s:property value="s_id"/> <s:debug></s:debug> </body> </html>
url:http://localhost:8080/structs2-HelloWorld01/Teacher.action?t_id=21
结果:控制台输出21,页面也是21,在值栈中同时存在t_id和s_id。这就是别名的作用,共享同一个参数值。
源码分析:
com.opensymphony.xwork2.interceptor.AliasInterceptor:
@Override public String intercept(ActionInvocation invocation) throws Exception { ActionConfig config = invocation.getProxy().getConfig(); ActionContext ac = invocation.getInvocationContext(); Object action = invocation.getAction(); // get the action's parameters final Map<String, String> parameters = config.getParams(); if (parameters.containsKey(aliasesKey)) { String aliasExpression = parameters.get(aliasesKey); ValueStack stack = ac.getValueStack(); Object obj = stack.findValue(aliasExpression); if (obj != null && obj instanceof Map) { //get secure stack ValueStack newStack = valueStackFactory.createValueStack(stack); boolean clearableStack = newStack instanceof ClearableValueStack; if (clearableStack) { //if the stack's context can be cleared, do that to prevent OGNL //from having access to objects in the stack, see XW-641 ((ClearableValueStack)newStack).clearContextValues(); Map<String, Object> context = newStack.getContext(); ReflectionContextState.setCreatingNullObjects(context, true); ReflectionContextState.setDenyMethodExecution(context, true); ReflectionContextState.setReportingConversionErrors(context, true); //keep locale from original context context.put(ActionContext.LOCALE, stack.getContext().get(ActionContext.LOCALE)); } // override Map aliases = (Map) obj; for (Object o : aliases.entrySet()) { Map.Entry entry = (Map.Entry) o; String name = entry.getKey().toString(); String alias = (String) entry.getValue(); Object value = stack.findValue(name); if (null == value) { // workaround Map<String, Object> contextParameters = ActionContext.getContext().getParameters(); if (null != contextParameters) { value = contextParameters.get(name); } } if (null != value) { try { newStack.setValue(alias, value); } catch (RuntimeException e) { if (devMode) { String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{ "Unexpected Exception caught setting '" + entry.getKey() + "' on '" + action.getClass() + ": " + e.getMessage() }); LOG.error(developerNotification); if (action instanceof ValidationAware) { ((ValidationAware) action).addActionMessage(developerNotification); } } } } } if (clearableStack && (stack.getContext() != null) && (newStack.getContext() != null)) stack.getContext().put(ActionContext.CONVERSION_ERRORS, newStack.getContext().get(ActionContext.CONVERSION_ERRORS)); } else { if (LOG.isDebugEnabled()) { LOG.debug("invalid alias expression:" + aliasesKey); } } } return invocation.invoke(); }
拦截器有一个参数:aliasesKey,可通过在struts.xml中定义该拦截器时指定其值,默认值是aliases,表示一个别名的map。param标签的name属性值应该和拦截器参数aliasesKey的值一样,这样拦截器才知道你是否指定了action的别名map。
1:得到struts.xml中action的paramters。
2:看是否包含了aliasesKey,如果包含了,那么说明存在一个别名map。
3:迭代这个map中的每项,将该项的别名和值也写入值栈中。
作者:keep_moving_cqu 发表于2013-12-5 2:06:39 原文链接
阅读:105 评论:0 查看评论