TokenInterceptor 防止表单重复提交。
由于某些原因,用户在进行类似表单提交的操作后,以为表单未被提交,会进行多次的重复提交。为了避免用户多次提交给服务器带来负荷。我们会对表单提交这样的操作进行一些处理,以告诉用户不要重复提交。下面我们建立
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
语句在重复提交时并未打印出来)
,而是此拦截器判断出是重复后直接返回上一次提交转向的页面。