[Struts2应用开发] 统一的登录验证

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

原文地址:https://www.cnblogs.com/enixyu/p/2686483.html