Struts2拦截器----AliasInterceptor分析

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中的每项,将该项的别名和值也写入值栈中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值