struts2 自定义拦截器

一、为什么要自定义拦截器

在struts2里面有很多拦截器,这些拦截器是struts2封装的功能,但是在实际开发中,struts2里面拦截器中可能没有要使用的功能,这个时候需要自己写拦截器实现功能

二、拦截器的结构

1、源代码看拦截器结构
  • 继承类


    image.png

    image.png
  • 在接口里面有三个方法


    image.png

    image.png

    image.png
2、开发中写类,继承
  • 继承MethodFilterInterceptor:它可以让action里一些方法不进行拦截
3、让拦截器和action有关系
  • 不是action调用拦截器的方法,而是通过配置文件方式建立关系

三、自定义登录拦截器

1、需求

在项目中,有许多action的超链接,实现只有是登录的状态,才可以点击action的超链接实现功能,如果不是登录,点击action链接返回登录页面

2、登录状态:session域对象实现
  • 登录成功后,把数据放到session里面
  • 判断session是否有值,可以知道登录状态
3、实现登录的基本功能

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'login.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    <div align="center">
        <h1>Login</h1>
        <h3 style="color: red">${requestScope.msg }</h3>
        <form action="${pageContext.request.contextPath }/checklogin" method="post">
            username:<input type="text" name="username"/><br><br>
            passwork:<input type="password" name="password"/><br><br>
            <input type="submit" value="login"/>
        </form>
    </div>
  </body>
</html>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>
  
  <body>
    <c:if test="${''!=sessionScope.username && null!=sessionScope.username }">
        欢迎 ${sessionScope.username }
    </c:if>
    <c:if test="${''==sessionScope.username || null==sessionScope.username }">
        <a href="${pageContext.request.contextPath }/login.jsp"> 您好请登录!</a>
    </c:if> 
    <br>
      <a href="${pageContext.request.contextPath }/hehe">点我·····</a>
    <br>
    <a href="${pageContext.request.contextPath }/haha">点我·····</a>
  </body>
</html>

CheckLogin.java

package work.zhangdoudou.Action;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import work.zhangdoudou.Bean.UserBean;

public class CheckLogin extends ActionSupport implements ModelDriven<UserBean>{
    private UserBean user;

    @Override
    public String execute() throws Exception {
        
        HttpServletRequest request=ServletActionContext.getRequest();
        if ("manman".equals(user.getUsername())&&"520".equals(user.getPassword())) {
            // 登录成功
            //向session放值
            request.getSession().setAttribute("username", user.getUsername());
            System.out.println(SUCCESS);
            return SUCCESS;
        }else{
            //登录失败
            request.setAttribute("msg", "账号或密码错误!");
            System.out.println(ERROR);
            return ERROR;
        }
    }
    
    @Override
    public UserBean getModel() {
        if (null==user) {
            user=new UserBean();
        }
        return user;
    }
}

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="false" value="struts.enable.DynamicMethodInvocation"/>
    <constant value="true" name="struts.devMode"/>
    <package name="default" extends="struts-default" namespace="/">
        <!--name:访问名称 -->
        
        <action name="checklogin" method="execute" class="work.zhangdoudou.Action.CheckLogin">
            <result name="success">/index.jsp</result>
            <result name="error">/login.jsp</result>
        </action>
        
    </package>
</struts>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>struts2.Filter</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
</web-app>
4、添加登陆拦截器

(1)判断是否登录:判断session里面是否有username的值
(2)拦截器的实现过程

  • 创建一个类,继承MethodFilterInterceptor类
  • 重写MethodFilterInterceptor里的方法,写拦截器逻辑

拦截器类Filter.java

package work.zhangdoudou.Filter;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.client.Invocation;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

public class Filter extends MethodFilterInterceptor{
    //这个方法里面写拦截器逻辑
    @Override
    protected String doIntercept(ActionInvocation invocation) throws Exception {

        //判断session是否有username值
        //得到session
        HttpServletRequest request=ServletActionContext.getRequest();
        Object object=request.getSession().getAttribute("username");
        //判断
        if (null!=object) {
            //登陆状态
            //做类似于放行操作
            return invocation.invoke();
        }else{
            //不是登陆状态
            //不登录不执行action的方法,返回登陆页面
            request.setAttribute("msg", "请登录!");
            return "error";
        }   
    }
}

(3)配置action和拦截器的关系(注册拦截器)

  • 在要拦截的action标签所在的package标签里声明拦截器
  • 在具体的action标签里使声明的拦截器
  • struts2里面执行很多默认拦截器,但是如果在action里面配置自定义拦截器
    问题:默认的拦截器不会执行了
    解决:把默认的手动配置一次
    特点:配置的拦截器会对action所有方法都会拦截
    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="false" value="struts.enable.DynamicMethodInvocation"/>
    <constant value="true" name="struts.devMode"/>
    <package name="default" extends="struts-default" namespace="/">
        
        <!-- 声明拦截器 -->
        <interceptors>
            <interceptor name="login" class="work.zhangdoudou.Filter.Filter"></interceptor> 
        </interceptors>
    
    
        <!--name:访问名称 -->
        <action name="checklogin" method="execute" class="work.zhangdoudou.Action.CheckLogin">
            <result name="success">/index.jsp</result>
            <result name="error">/login.jsp</result>
        </action>
        
        
        <action name="hehe" method="execute" class="work.zhangdoudou.Action.hehe">
            <!-- 使用自定义的拦截器 -->
            <interceptor-ref name="login"></interceptor-ref>
            <!-- 默认拦截器手动使用一次 -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            
            <result name="success">/index.jsp</result>
            <result name="error">/login.jsp</result>
        </action>
        
    </package>
</struts>
5、配置拦截器,不要对action的所有方法都进行拦截
  • 直接通过配置方式让action里面某些方法不进行拦截
    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="false" value="struts.enable.DynamicMethodInvocation"/>
    <constant value="true" name="struts.devMode"/>
    <package name="default" extends="struts-default" namespace="/">
        
        <!-- 声明拦截器 -->
        <interceptors>
            <interceptor name="login" class="work.zhangdoudou.Filter.Filter"></interceptor> 
        </interceptors>
    
    
        <!--name:访问名称 -->
        <action name="checklogin" method="execute" class="work.zhangdoudou.Action.CheckLogin">
            <result name="success">/index.jsp</result>
            <result name="error">/login.jsp</result>
        </action>
        
        
        <action name="hehe" method="execute" class="work.zhangdoudou.Action.hehe">
            <!-- 使用自定义的拦截器 -->
            <interceptor-ref name="login"></interceptor-ref>
            <!-- 默认拦截器手动使用一次 -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            
            <result name="success">/index.jsp</result>
            <result name="error">/login.jsp</result>
        </action>
        
        <action name="haha" method="haha" class="work.zhangdoudou.Action.hehe">
            <!-- 使用自定义的拦截器 -->
            <interceptor-ref name="login">
                <!-- 配置某些方法不进行拦截 name属性excludeMethods -->
                <param name="excludeMethods">haha</param>
            </interceptor-ref>
            <!-- 默认拦截器手动使用一次 -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            
            <result name="success">/index.jsp</result>
            <result name="error">/login.jsp</result>
        </action>
        
    </package>
</struts>
6、实现效果

点击拦截进行登录


image.png

image.png

点击不拦截


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容