在日常的開發過程中,我們時常需要在做某個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都會通過該攔截器驗證用戶是否已登錄,再執行相應的操作。從而達到統一的用戶登錄驗證。