在日常的开发过程中,我们时常需要在做某个Action操作前,验证用户是否已登录,若用户尚未登录,则跳转至登录页面;若已登录,则获取当前的用户信息,并进行下一步的操作。
Struts2访问Session
获取用户信息,我们自然想到了Session。而在Struts2中访问Session可以通过两种途径:
1. 通过ActionContext中的getSession方法来回获取Session存储对象
import java.util.Map; import org.apache.struts2.interceptor.SessionAware; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport implements SessionAware { private Map session; public void setSession(Map session) { this.session = session; } public String execute() { this.session.put("USER_NAME", "ENIX"); return SUCCESS; } }
2. 通过实现SessionAware接口,并实现setSession方法来操作Session对象。
import java.util.Map; import org.apache.struts2.interceptor.SessionAware; public class BaseAction implements SessionAware{ //Session Map对象 protected Map<String, Object> session; @Override public void setSession(Map<String, Object> session) { this.session = session; } public Map<String, Object> getSessionMap(){ return this.session; } public String execute(){ this.session.put("USER_NAME", "ENIX"); return SUCCESS; } }
对于以上两种途径,个人比较喜欢第二种,因为第二种更符合Struts2的设计理念,更方便于做单元测试。
通过Session的Map对象,我们可以方便的访问用户的登录信息,但是随之而来的问题是,对于系统每一个Action,我们都需要重新去读取Session里面的USER_NAME,然后再判断是否登录吗?这样显然不合理。Struts2提供了另外一个途径来解决这个问题——拦截器(Interceptor)。
Struts2拦截器
自定义自己的拦截器可以通过继承AbstractInterceptor类,并实现intercept方法:
以下的BaseAction是所有Action的父类,并通过继承SessionAware接口实现Session的访问。下面的拦截器就是通过获取被拦截的Action对象后,转化为其父类,并读取session值,判断用户是否已登录。
import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class LoginInterceptor extends AbstractInterceptor { private static final long serialVersionUID = 1L; @Override /* * 验证是否已登录 * LOGIN_TYPE = 1 :已登录 * LOGIN_TYPE = 0 :未登录 */ public String intercept(ActionInvocation invocation) throws Exception { BaseAction baseAction = (BaseAction)invocation.getAction(); Map<String, Object> sessionMap = baseAction.getSessionMap(); int LOGIN_TYPE = sessionMap.get("LOGIN_TYPE") == null ? 0 : (Integer)sessionMap.get("LOGIN_TYPE"); if(LOGIN_TYPE != 1){ return Action.LOGIN; } else{ return invocation.invoke(); } } }
Struts.xml中的配置如下:
1. 首先定义拦截器 interceptor
2. 定义默认拦截器default-interceptor-ref
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="ptsystem" extends="json-default"> <!-- 拦截器 --> <interceptors> <!-- 登录验证 --> <interceptor name="loginVerify" class="LoginInterceptor"></interceptor> <interceptor-stack name="verify"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="loginVerify"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="verify"></default-interceptor-ref> <!-- 错误处理Action --> <global-results> <result name="error">Error.jsp</result> <result name="login">Login.jsp</result> </global-results> <action name="catgList" class="CatgListAction" method="delType"> <result name="success"> /catg.jsp </result> </action> ......
通过默认拦截器的定义,所有Action都会通过该拦截器验证用户是否已登录,再执行相应的操作。从而达到统一的用户登录验证。