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拦截器链中的拦截器就会按其之前定义的顺序被依次调用。

  • 拦截器的调用流程


    13424350-9177873ab221d687.png
    调用拦截器的流程

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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值