我正在尝试使用Interceptor
来限制用户执行某些操作。
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
,则应将用户重定向到索引页。
但是,我收到NullPointerException
,说session
为空,正如if-check验证的那样。
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>
为什么session
为空以及如何解决?
(This是我使用的参考。)
答案 0 :(得分:2)
基于this我不认为拦截器本身可以/需要能够识别会话。
您可以这样访问此媒体资源:
final ActionContext context = actionInvocation.getInvocationContext();
this.session = context.getSession();
可能有一种方法可以自动获取此设置,我对struts2不太熟悉,但可能是sessionaware仅适用于特定的对象子集,而且由于某种原因,这个拦截器不是其中之一。 (未被扫描,被排除在扫描之外,类型错误)
答案 1 :(得分:2)
Struts Session只是Map<String,Object>
包装基础HttpSession
。
在实现SessionAware接口is the correct way to get it in an 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">