表單重復(fù)提交的概述
若刷新表單頁(yè)面客税,再提交表單不算重復(fù)提交惨恭。
若是重定向系草,已經(jīng)提交成功后再刷新不算重復(fù)提交通熄。
以下幾種情況算是表單重復(fù)提交
多次點(diǎn)擊提交按鈕
已經(jīng)提交成功,按"回退"之后找都,再點(diǎn)擊"提交按鈕"
在控制器響應(yīng)頁(yè)面的形式為轉(zhuǎn)發(fā)情況下唇辨,若已經(jīng)提交成功,然后點(diǎn)擊"刷新"重復(fù)提交的缺點(diǎn)
加重了服務(wù)器的負(fù)擔(dān)
可能導(dǎo)致錯(cuò)誤操作
Struts2解決表單重復(fù)提交
在
<s:form >
標(biāo)簽中添加<s:token>
子標(biāo)簽
生成一個(gè)隱藏域
在session
添加一個(gè)屬性值
隱藏域的值和session
的屬性值是一致的使用
Token
或TokenSession
攔截器
這兩個(gè)攔截器均不在默認(rèn)的攔截器棧中能耻,所以需要手工配置一下
若使用Token
攔截器赏枚,則需要配置一個(gè)token.valid
的result
若使用TokenSession
攔截器,則不需要配置任何其它的result
Token
與TokenSession
區(qū)別
都是解決表單重復(fù)提交問(wèn)題晓猛,但是使用token
攔截器會(huì)轉(zhuǎn)到token.valid
這個(gè)result
饿幅,使用tokenSession
攔截器則還會(huì)響應(yīng)那個(gè)目標(biāo)頁(yè)面,但不會(huì)執(zhí)行tokenSession
的后續(xù)攔截器戒职。可以使用
<s:actionerror>
標(biāo)簽來(lái)顯示重復(fù)提交的錯(cuò)誤消息栗恩,該錯(cuò)誤消息可以在國(guó)際化資源文件中覆蓋,該字段名為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中打印錯(cuò)誤消息:
<%@ 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攔截器概述
攔截器在訪問(wèn)某個(gè)Action方法之前或之后實(shí)施攔截
攔截器是可拔插的,攔截器是AOP的一種實(shí)現(xiàn)蚓曼。
攔截器棧將攔截器按一定的順序聯(lián)結(jié)成一條鏈,在訪問(wèn)被攔截的方法時(shí)钦扭,Struts2攔截器鏈中的攔截器就會(huì)按其之前定義的順序被依次調(diào)用纫版。
-
攔截器的調(diào)用流程
調(diào)用攔截器的流程
Interceptor接口
Struts會(huì)依次調(diào)用為某個(gè)Action而注冊(cè)的每一個(gè)攔截器的
intercept
方法每次調(diào)用
intercept
方法時(shí),Struts會(huì)傳遞一個(gè)ActionInvocation
接口的實(shí)例ActionInvocation
代表一個(gè)給定ActionAction
的執(zhí)行狀態(tài)客情,攔截器可以從該類(lèi)的對(duì)象里獲得與該Action相關(guān)聯(lián)的Action對(duì)象和Result對(duì)象其弊,在完成攔截器自己的任務(wù)之后,攔截器將調(diào)用ActionInvocation
對(duì)象的invoke
方法前進(jìn)到Action處理流程的下一個(gè)環(huán)節(jié)AbstractInterceptor
類(lèi)實(shí)現(xiàn)了Interceptor
接口膀斋,并為init
梭伐,destory
提供了一個(gè)空白的實(shí)現(xiàn)。
自定義攔截器
定義一個(gè)攔截器的類(lèi)
可以實(shí)現(xiàn)Interceptor
接口
也可以繼承AbstractInterceptor
抽象類(lèi)在
struts.xml
文件中配置注意:在自定義的攔截器中可以選擇不調(diào)用
ActionInvocation
的invoke()
方法仰担,那么后續(xù)的攔截器和Action方法將不會(huì)被調(diào)用糊识。Struts2會(huì)渲染自定義攔截器intercept
方法返回值對(duì)應(yīng)的result
示例:
定義攔截器類(lèi)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("調(diào)用actionInvocation.invoke之前");
String result = actionInvocation.invoke();
System.out.println("調(diào)用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>