• 【基于初学者的SSH】struts2 的拦截器、令牌的简单应用及理解


    一:拦截器与过滤器类似,但是它们的区别也很大:

    01):过滤器理论上可以过滤任意内容,比如HTML,servlet,jsp,图片路径

    02):拦截器只可以拦截action。

    二:拦截器的原理 

    action对象创建之后,在执行action的方法之前会执行拦截器,这里的思想就是aop(面向切面编程):简单来说就是在不修改代码的情况下来扩展功能用的,比如要做一个带权限的登录,在登录成功之前就可以加上权限的判断,但是不需要去修改源代码,而又扩展了功能。还有责任链模式:多个拦截器的执行过程采用的就是责任链模式,当一个拦截器执行完并放行才能执行下一个拦截器,如果第一个拦截器不放行,后面的拦截器都不会执行,且要所有的拦截器都执行完才会去自信心action方法,但是在配置拦截器的时候可以配置某个方法过滤不拦截,这点我下面贴出来的代码中会有,注意看注释就知道那个是了。

    三:token令牌 

    01):令牌的生成原理

    浏览器发出请求到服务器,服务器检查是否有token标签,如果没有,则会在session里面保存token id,如果已经有了token id,则会覆盖,如果服务器有token标签,就将jsp页面的token标签转化成token id再回到浏览器。

    02):令牌的拦截原理

    向某个action发出请求,根据struts的配置文件判断是否拦截改方法,需要拦截,判断提交的token id和session中的id是否相等,相等,清空session中的token id,不相等则根据配置跳转到指定页面。 

    四:用令牌做一个防止数据重复提交的实例 

    01):jsp页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@taglib prefix="s"   uri="/struts-tags"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <s:form  action="login.action"   method="post">
    <!-- 注意一定要加上token标签,否则不会生成token id -->
    <s:token></s:token>
    <s:textfield  name="uname"></s:textfield><br>
    <s:password  name="upwd" ></s:password><br>
    <s:submit  value="提交"></s:submit>
    </s:form>
    </body>
    </html>

    02):web.xml 里面加上一段

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>

    03):TokenAction

    public String execute() throws Exception {
            HttpServletRequest request=ServletActionContext.getRequest();
            String name=request.getParameter("uname");
            String pwd=request.getParameter("upwd");
            System.out.println(name+"---"+pwd);
            return SUCCESS;
        }

    04):struts.xml

        <package name="mypackage" extends="struts-default">
            <action name="token*" class="com.action.TokenAction" method="{1}">
                <!-- 配置令牌 -->
                <interceptor-ref name="token"></interceptor-ref>
                <!-- 引入默认的拦截器 action转换到action类中 -->
                <interceptor-ref name="defaultStack"></interceptor-ref>
                <result name="success">/success.jsp</result>
                <!-- 挡在session中已经找到相同值进行跳转 -->
                <result name="invalid.token">/error.jsp</result>
            </action>
        </package>

    注:在执行方法之前永远都会先执行拦截器,默认的拦截器在action类实例化以后执行 

    五:自定义拦截器 (登录的实例,判断是否登录)

    01):jsp页面,给上name的值以便获取,怎么获取表单的值我上篇博客有写

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>登录</title>
    </head>
    <body>
    <form action="adminlogin.action"  method="post">
    <input  name="uname"><br>
    <input  name="upwd"  type="password"><br>
    <input  type="submit"  value="提交">
    </form>
    </body>
    </html>

    02):action类,这里我就没过数据库了,直接自己判断了下

    public class InterceptorAction extends ActionSupport {
    
        public String login() {
            HttpServletRequest request = ServletActionContext.getRequest();
            HttpSession session = request.getSession();
            String name = request.getParameter("uname");
            String pwd = request.getParameter("upwd");
            if ("admin".equals(name) && "123".equals(pwd)) {
                session.setAttribute("name", name);
                return SUCCESS;
            } else {
                return LOGIN;
            }
    
        }
    
    }

    03):下面就开始写自定义拦截器了,首先创建类继承MethodFilterInterceptor类,重写MethodFilterInterceptor类里面拦截器的方法

    public class MyInterceptor extends MethodFilterInterceptor {
    
        @Override
        protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
            HttpServletRequest request = ServletActionContext.getRequest();
            String name = (String) request.getSession().getAttribute("name");
            // 判断是否有session
            if (name != null) {
                // 取到继续执行(放行)
                actionInvocation.invoke();
                return Action.SUCCESS;
            } else {
                // 没有获取到返回一个界面
                return Action.LOGIN;
            }
        }
    
    }

    04): struts.xml 配置action和自定义拦截器直接的关系(注册拦截器)

        <package name="mylogin" extends="struts-default">
            <!-- 创建拦截器 -->
            <interceptors>
                <interceptor name="MyInterceptor" class="com.interceptor.MyInterceptor"></interceptor>
            </interceptors>
            <action name="admin*" class="com.action.InterceptorAction"
                method="{1}">
                <!-- 引用拦截器 -->
                <interceptor-ref name="MyInterceptor">
                    <!-- 排除方法 -->
                    <param name="excludeMethods">login</param>
                </interceptor-ref>
                <result name="success">/success.jsp</result>
                <result name="login">/interceptorlogin.jsp</result>
            </action>
        </package>

    注:这里必须要先过滤登录的方法,不然获取不要session拦截器无法判断,这样的话永远都是跳到登录页面 

     

  • 相关阅读:
    css中后代、元素、类、id选择器以及行间style优先级的比较
    JS小功能x系列6文字自动滚动
    JS小功能系列7自动打字
    JS小功能系列6折叠
    JS小功能系列5图片左右移动
    JS小功能系列4图片轮播综合数字轮播,顺时针逆时针,自动轮播
    JS小功能系列3时钟
    JS小功能系列2商品计算
    JS小功能系列1换一批
    JS隔行变色,鼠标悬停变色
  • 原文地址:https://www.cnblogs.com/hxbhdljmyz/p/7702547.html
Copyright © 2020-2023  润新知