撰文记录,方便查阅
正在学习使用struts2的拦截器,代码略过,action配置如下:
<package name="userLogin" namespace="" extends="struts-default">
<!-- 拦截器 -->
<interceptors>
<interceptor name="parameters" class="com.zwm.action.filter.ParameterInterceptor"></interceptor>
</interceptors>
<action name="userLogin/*" method="{1}" class="com.zwm.action.LoginAction">
<interceptor-ref name="parameters"></interceptor-ref>
</action>
</package>
运行程序发现 实现ServletRequestAware,ServletResponseAware, SessionAware等接口获取的,request,response对象都为null.
大家都知道struts2有个默认的拦截器 defaultStack, 自定义配置的拦截器会覆盖struts2的默认拦截器.为配置自定义拦截器之前,程序是正常的,所以怀疑request等对象是由defaultStack注入进去的。defaultStack拦截器在struts2-core-2.3.24.jar包中的struts-default.xml配置,通过反编译或者源码找到默认拦截器的配置,代码如下:
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
<interceptor-ref name="deprecation"/>
</interceptor-stack>
看拦截器名称可以判断,具体的实现过程应该在 <interceptor-ref name="servletConfig"/>拦截器中
直接查找servletConfig拦截器: <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
根据包路径打开源码:
public class ServletConfigInterceptor extends AbstractInterceptor
implements StrutsStatics
{
private static final long serialVersionUID = 605261777858676638L;
public String intercept(ActionInvocation invocation)
throws Exception
{
HttpServletRequest request;
Object action = invocation.getAction();
ActionContext context = invocation.getInvocationContext();
if (action instanceof ServletRequestAware) {
request = (HttpServletRequest)context.get("com.opensymphony.xwork2.dispatcher.HttpServletRequest");
((ServletRequestAware)action).setServletRequest(request);
}
if (action instanceof ServletResponseAware) {
HttpServletResponse response = (HttpServletResponse)context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse");
((ServletResponseAware)action).setServletResponse(response);
}
if (action instanceof ParameterAware) {
((ParameterAware)action).setParameters(context.getParameters());
}
if (action instanceof ApplicationAware) {
((ApplicationAware)action).setApplication(context.getApplication());
}
if (action instanceof SessionAware) {
((SessionAware)action).setSession(context.getSession());
}
if (action instanceof RequestAware) {
((RequestAware)action).setRequest((Map)context.get("request"));
}
if (action instanceof PrincipalAware) {
request = (HttpServletRequest)context.get("com.opensymphony.xwork2.dispatcher.HttpServletRequest");
if (request != null)
{
((PrincipalAware)action).setPrincipalProxy(new ServletPrincipalProxy(request));
}
}
if (action instanceof ServletContextAware) {
ServletContext servletContext = (ServletContext)context.get("com.opensymphony.xwork2.dispatcher.ServletContext");
((ServletContextAware)action).setServletContext(servletContext);
}
return invocation.invoke();
}
}
发现servlet 的相关配置都是在这里实现的。
所以在自定义的拦截器中一定要加上默认的拦截器 <interceptor-ref name="defaultStack"></interceptor-ref>
或者将相关需要实现的拦截器功能 在自定义的拦截器中实现