34.TokenInterceptor防止表单重复提交

转自:https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html

由于某些原因,用户在进行类似表单提交的操作后,以为表单未被提交,会进行多次的重复提交。为了避免用户多次提交给服务器带来负荷。我们会对表单提交这样的操作进行一些处理,以告诉用户不要重复提交。下面我们建立struts2token项目,使用struts2的token拦截器来实现此案例。
步骤一,编写login.jsp页面,内容如下:
<%@ page language="java" pageEncoding="UTF-8"%>

<%@ taglib uri="/struts-tags" prefix="s" %>

<html>

       <body>

              <form action="<%=request.getContextPath()%>/login.action" >

                     姓名:<input type="text" name="username"><br>

                     密码:<input type="password" name="password"><br>

                     <input type="submit" value="登录">

                     <s:token></s:token>

              </form>

       </body>

</html>
说明,此登录页面中的关键技术就是使用了标签库中的<s:token></s:token>标签,它的作用就是在用户访问此页面时会生成一个sessionId,在提交时会服务器会据此验证表单是否已提交。“To set a token in your form, you should use the token tag. This tag is required and must be used in the forms that submit to actions protected by this interceptor”,这句话的大概意思就是我们必须要在提交的表单中使用这个token tag,这样提交到的Action便能配置TokenInterceptor拦截器验证表单是否重复提交。
步骤二,编写LoginAction,主要代码如下:
package com.asm;
public class LoginAction extends ActionSupport {

       public String execute() throws Exception {

              System.out.println("---->执行execute方法...");

              return SUCCESS;

       }

}
步骤三,struts.xml主要配置内容如下:
<struts>

       <package name="tokenTest" extends="struts-default">

              <action name="login" class="com.asm.LoginAction">

                     <result name="success">/success.jsp</result>

                     <result name="invalid.token">/subError.jsp</result>

                     <interceptor-ref name="token"></interceptor-ref>

                     <interceptor-ref name="defaultStack"></interceptor-ref>

              </action>

       </package>

</struts>

说明:在此Action下,我们配置了token拦截器,另注意到在此Action下我们还配置了一个“invalid.token”result,因为“This interceptor uses a fairly primitive technique for when an invalid token is found: it returns the result invalid.token, which can be mapped in your action configuration”。它的大概意思就是:提交时服务器如果根据token标签产生的sessionId判断出表单已提交,它则返回invalid.token指向的视图。比如这里,如果重复提交则会转到.../subError.jsp中去。另不要忘记了引入默认的拦截器栈。补充:关于token拦截器更多细节可以访问org.apache.struts2.interceptor.TokenInterceptor类的api说明。
步骤四,编写配置中所用到jsp页面,这些页面编写简单,在此省去。
步骤五、发布测试,请注意访问login.jsp页面时,查看源文件时会发现增加了两个隐藏域信息。
步骤六、更换拦截器:我们还可以使用tokenSession拦截器,它的功能比上面的增强,它能保证持有相同sessionId的并发请求等待第一个完成之后才能被提交处理,但是它返回的是action执行后的result.接着上例,我们只需要在配置中作如下修改:把上面的token拦截器改成<interceptor-ref name="tokenSession"></interceptor-ref> 即可。随后便可以测试,测试时会发现如果我们重复提交,它总是返回到上一次的success.jsp页面,但是它并不是经过LoginAction中的execute处理后返回(我们System.out.print语句在重复提交时并未打印出来),而是此拦截器判断出是重复后直接返回上一次提交转向的页面。

原文地址:https://www.cnblogs.com/sharpest/p/5587622.html