Struts2学习笔记 | 防止表单重复提交及自定义拦截器

表单重复提交的概述

  • 若刷新表单页面,再提交表单不算重复提交。

  • 若是重定向,已经提交成功后再刷新不算重复提交

  • 以下几种情况算是表单重复提交
    多次点击提交按钮
    已经提交成功,按"回退"之后,再点击"提交按钮"
    在控制器响应页面的形式为转发情况下,若已经提交成功,然后点击"刷新"

  • 重复提交的缺点
    加重了服务器的负担
    可能导致错误操作

Struts2解决表单重复提交

  • <s:form >标签中添加<s:token>子标签
    生成一个隐藏域
    session添加一个属性值
    隐藏域的值和session的属性值是一致的

  • 使用TokenTokenSession拦截器
    这两个拦截器均不在默认的拦截器栈中,所以需要手工配置一下
    若使用Token拦截器,则需要配置一个token.validresult
    若使用TokenSession拦截器,则不需要配置任何其它的result

  • TokenTokenSession区别
    都是解决表单重复提交问题,但是使用token拦截器会转到token.valid这个result,使用tokenSession拦截器则还会响应那个目标页面,但不会执行tokenSession的后续拦截器。

  • 可以使用<s:actionerror>标签来显示重复提交的错误消息,该错误消息可以在国际化资源文件中覆盖,该字段名为struts.messages.invalid.token,可以在struts-messages.properties文件中找到。

使用token拦截器的配置示例:

<action name="testToken" class="com.cerr.struts2.TokenAction">
            <interceptor-ref name="token"></interceptor-ref>
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <result>/success.jsp</result>
            <result name="invalid.token">/token-error.jsp</result>
</action>

在token-error.jsp中打印错误消息:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
  Created by IntelliJ IDEA.
  User: 白菜
  Date: 2019/8/7
  Time: 21:25
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <s:actionerror></s:actionerror>
</body>
</html>


Struts2拦截器概述

  • 拦截器在访问某个Action方法之前或之后实施拦截

  • 拦截器是可拔插的,拦截器是AOP的一种实现。

  • 拦截器栈将拦截器按一定的顺序联结成一条链,在访问被拦截的方法时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用。

  • 拦截器的调用流程


    调用拦截器的流程

Interceptor接口

  • Struts会依次调用为某个Action而注册的每一个拦截器的intercept方法

  • 每次调用intercept方法时,Struts会传递一个ActionInvocation接口的实例

  • ActionInvocation代表一个给定ActionAction的执行状态,拦截器可以从该类的对象里获得与该Action相关联的Action对象和Result对象,在完成拦截器自己的任务之后,拦截器将调用ActionInvocation对象的invoke方法前进到Action处理流程的下一个环节

  • AbstractInterceptor类实现了Interceptor接口,并为initdestory提供了一个空白的实现。

自定义拦截器

  • 定义一个拦截器的类
    可以实现Interceptor接口
    也可以继承AbstractInterceptor抽象类

  • struts.xml文件中配置

  • 注意:在自定义的拦截器中可以选择不调用ActionInvocationinvoke()方法,那么后续的拦截器和Action方法将不会被调用。Struts2会渲染自定义拦截器intercept方法返回值对应的result

示例:
定义拦截器类myInterceptor:

package com.cerr.struts2.interceptors;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class myInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {
        System.out.println("调用actionInvocation.invoke之前");
        String result = actionInvocation.invoke();
        System.out.println("调用actionInvocation.invoke之后");
        return result;
    }
}

配置及使用:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <package name="default" namespace="/" extends="struts-default">
      <interceptors>
            <!-- 配置-->
            <interceptor name="hello" class="com.cerr.struts2.interceptors.myInterceptor"></interceptor>
       </interceptors>
     
        <action name="testToken" class="com.cerr.struts2.TokenAction">
            <!-- 使用-->
            <interceptor-ref name="hello"></interceptor-ref>
            <interceptor-ref name="token"></interceptor-ref>
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <result>/success.jsp</result>
            <result name="invalid.token">/token-error.jsp</result>
        </action>
    </package>
</struts>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容