Struts2防止表单重复提交

来源:互联网 发布:phpo2o源码 编辑:程序博客网 时间:2024/06/10 02:34
1.    预备知识:
a)      拦截器配置
在struts-default.xml中定义了很多拦截器,这些拦截器就是用来完成许多强劲功能的保证,而且可以根据已定义的若干拦截器中的某几个拦截器构建成interceptor-stack拦截器栈,其实拦截器栈还可以由拦截器栈组成。即从Struts2高层的角度来看,二者没有什么区别。
我们可以在<package/>中增加这样一行<default-interceptor-ref name="拦截器的名字"/>即表示将该拦截器作为整个包的默认拦截器,它会自动附加到我们的每一个Action中。并且在一个<package/>中只能使用<default-interceptor-ref/>定义一个默认的拦截器。
若<action/>没有引用任何一个拦截器,那么默认的defaultStack会自动附加到<action/>中
若<action/>手工引用任何一个拦截器,那么默认的defaultStack就不会附加到<action/>中
若还想使用默认拦截器,则只能再通过手工方式导入<interceptor-ref name="defaultStack"/>

如果没有引用Struts2的默认拦截器,那么就会影响到整体的输入校验即其它的一些功能
Struts2拦截器的配置和使用都很easy,这得益于其底层的良好架构以及它的AOP的思想
该拦截器即标准的AOP思想,代码不写死到Action里,而是根据配置灵活附加到Action中
使用上,Struts2拦截器并不复杂。但实现上,是很复杂的,其底层用到了动态代理的机制
 

b)      造成重复提交主要的两个原因:
 

1)            一是,服务器处理时间久。当用户在表单中填完信息,点击“提交”按钮后,由于服务器反应时间过长没能及时看到响应信息,或者出于其它目的,再次点击“提交”按钮,从而导致在服务器端接收到两条或多条相同的信息。如果信息需要存储到后台数据库中,如此以来就会产生数据库操作异常提示信息,以至于给用户带来错误信息提示,从而给用户的使用带来不便。
 

2)            二是,forward跳转引起的重复提交。当用户将信息提交到服务器,服务器响应采用forward方式调转到下一个页面后,此时地址栏中显示的是上个页面的URL,若刷新当前页面,浏览器会将再次提交用户先前输入的数据,就会再次出现表单重复提交的问题。当然你可以选择redirect方式跳转页面,这样就不会出现重复提交的问题;但有时为了达到某种效果或式。者出于网站安全的目的需要隐藏网页跳转,而不得不采用forward跳转方
 

c)       对token的简单理解:
1)当用户首次访问包含表单的页面时,服务器会在这次会话中创建一个session对象,并产生一个令牌值,然后将这个令牌值作为隐藏输入域的值,随表单一起发送到服务器端,同时将令牌值保存到Session中。
2) 当用户提交页面时,服务器首先判断请求参数中的令牌值和Session中保存的令牌值是否相等,若相等,则清楚Session中的令牌值,然后执行数据处理操作。如果不相等,则提示用户已经提交过了表单,同时产生一个新的令牌值,保存到Session中。当用户重新访问提交数据页面时,将新产生的令牌值作为隐藏输入域的值。
 

 

注意问题:请简述客户端跳转和服务器端跳转之间的区别
客户端跳转时用HttPservletResopse对象的sendRedirect函数实现,服务器端跳转是使用RequestDispather对象的forward方法实现的。这两者之间的区别主要体现在三个方面:
1. 使用服务器端跳转时,客户浏览器的地址栏并不会显示目标地址的URL,而是用客户端跳转时,地址栏当中会显示目标资源的URL;
2. 服务器端跳转是由客户端发送一个请求,请求一个服务器资源——如JSP和Servlet——,这个资源又将请求转到另一个服务器资源,然后再给客户端发送一个响应,也就是说服务器端跳转是客户端发送一次请求,服务器端给出一次响应;而客户端跳转的流程则不同。客户端同样是发送一个请求给服务器端资源,这个服务器资源会首先给客户端一个响应,客户端再根据这个响应当中所包含的地址,再次向服务器端发送一个请求,也就是说客户端跳转是两次请求,两次响应;
3.         在进行客户端跳转和服务器端跳转时,都需要指定目标资源的URL,如果这个路径以“/”开始。在客户端跳转当中“/”代表的是应用服务器根目录,而在服务器端跳转当中代表的是应用程序根目录。

 

2.开始解决
使用struts2  token拦截器
struts2的拦截器实现了防止表单重复提交的功能,即token拦截器,在表单提交页面写上<s:token/>,在struts.xml配置文件中相应的action上配置拦截器。此拦截器只能用在有form的提交请求上。
Jsp页面部分代码:
 

在表单提交页面写上<s:token/>
<s:form action="add" method="post">

    <s:token /><!-- 防止表单重复提交 -->
    <s:textfield name="userName" label="用户名"></s:textfield><br/>
    <s:password name="password" label="密码"></s:password><br/>
    <s:submit />

</s:form>
 

 在struts.xml配置文件中相应的action上配置拦截器
<action name="*" class="tutorial.UploadFiles" method="{1}">
<interceptor-ref name="token"></interceptor-ref>

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

<result name="invalid.token" type="dispatcher" >/error.jsp</result> <!--如果是重复提交跳转的页面,这个页面可以用actionError标签来提示重复提交信息The form has

already been processed or on token was supplied ,please try again.修改国际化文件struts.messages.invalid.token的键值,提供自己定制的错误信息,比如struts.messages.invalid.token="您已经提交了表单,请不要重复提交"

-->