我正在尝试使用Interceptor来限制用户执行某些操作。
Interceptor
ContainsKeyInterceptor :
ContainsKeyInterceptor
public class ContainsKeyInterceptor extends AbstractInterceptor implements SessionAware { private static final long serialVersionUID = 1L; private Map<String, Object> session; @Override public String intercept(ActionInvocation actionInvocation) throws Exception { if(session == null) { System.out.println("session is null"); } if(session.containsKey("currentId")) { return "index"; } String result = actionInvocation.invoke(); return result; } @Override public void setSession(Map<String, Object> session) { this.session = session; } }
如果currentId在中找到用户,则应该将用户重定向到索引页面session。
currentId
session
但是,我得到了一个NullPointerException,说session是空的,如if-check所验证。
NullPointerException
struts.xml :
struts.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.devMode" value="false" /> <!-- actions available to guests --> <package name="guest" extends="struts-default"> <interceptors> <interceptor name="containskeyinterceptor" class="com.mypackage.interceptor.ContainsKeyInterceptor" /> </interceptors> <action name="index" class="com.mypackage.action.IndexAction"> <interceptor-ref name="containskeyinterceptor" /> <result type="redirect">/index.jsp</result> <result name="index" type="redirect">/index.jsp</result> </action> <action name="login" class="com.mypackage.action.LoginAction"> <interceptor-ref name="containskeyinterceptor" /> <result type="redirect">/index.jsp</result> <result name="input">/login.jsp</result> <result name="index" type="redirect">/index.jsp</result> </action> </package> <!-- actions available to members --> <package name="member" extends="struts-default"> <action name="logout" class="com.mypackage.action.LogoutAction"> <result type="redirectAction"> <param name="actionName">index</param> </result> </action> </package> </struts>
为什么是sessionnull以及如何解决?
(这是我使用的参考。)
Struts Session只是Map<String,Object>底层的包装HttpSession。
Map<String,Object>
HttpSession
虽然实现SessionAware接口是在Action中获取它的正确方法,但是如果要从Interceptor中获取它,则需要执行以下操作:
要获取Struts 会话图 :
@Override public String intercept(ActionInvocation ai) throws Exception { final ActionContext context = ai.getInvocationContext(); // Struts Session Map<String, Object> session = context.getSession();
要获得真正的 HttpSession对象 :
@Override public String intercept(ActionInvocation ai) throws Exception { final ActionContext context = ai.getInvocationContext(); HttpServletRequest request = (HttpServletRequest)context.get(StrutsStatics.HTTP_REQUEST); // Http Session HttpSession session = request.getSession();
就是说,您没有在动作中获得会话(也没有其他任何参数,对象等)的原因是,您陷入一个常见错误: 仅应用一个 (您的) 拦截器, 而不是 应用整个拦截器堆栈 (其中应包含您的):
您可以在每个动作中定义两次:
<action name="login" class="ph.edu.iacademy.action.LoginAction"> <interceptor-ref name="defaultStack" /> <!-- this is missing --> <interceptor-ref name="containskeyinterceptor" />
或者更好的是,在自定义堆栈中定义一次,并始终使用堆栈:
<interceptors> <interceptor-stack name="yourStack"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="containskeyinterceptor"/> </interceptor-stack> </interceptors> <action name="login" class="ph.edu.iacademy.action.LoginAction"> <interceptor-ref name="yourStack" />
并最终使用default-interceptor-ref定义它,以避免为该程序包的每个操作配置编写它:
<default-interceptor-ref name="yourStack"/> <action name="login" class="ph.edu.iacademy.action.LoginAction">