在日常的开发过程中,我们时常需要在做某个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都会通过该拦截器验证用户是否已登录,再执行相应的操作。从而达到统一的用户登录验证。