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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章