Struts2(十五):解决表单的重复提交

一,重复提交及缺点

1.表单的重复提交:

  若刷新表单,再提交表单不算重复提交

  在不刷新表单的前提下:

  •  多次点击提交按钮
  •  已经提交成功,按“回退”之后,再提交“提交按钮”
  •   在控制器响应页面的形式为转发情况下,若已经提交成功,然后点击“刷新”
注意:
  • 若刷新表单页面,再提交表单不算重复提交
  • 若使用的是redirect的相应类型,已经提交成功后,再点击“刷新”,不是表单的重复提交

2.重复提交的缺点:

  •  可能加重了服务器的负担
  •  可能导致错误操作

二,解决表单的重复提交

1.步骤:

  • Struts2(十五):解决表单的重复提交

  (1)   在s:form标签中添加s:token子标签(Struts 提供的 token 标签可以用来生成一个独一无二的标记. 这个标签必须嵌套在 form 标签的内部使用, 它将在表单里插入一个隐藏字段并把标记值(隐藏域的字段的值)保存在HttpSession 对象里. )

  •  生成一个隐藏域
  •  在session里添加一个属性值
  •  隐藏域的值和session的属性值是一致的

    (2)使用Token或TokenSession拦截器栈(Token 标签必须与 Token 或 TokenSession 拦截器配合使用, 这两个拦截器都能对标记进行处理. )

  • 这两个拦截器栈没在默认的拦截器栈,需要手动配置
  •  使用Token拦截器,则需要配置一个token.valid的result
  •   使用TokenSession拦截器,则不需要配置任何其他的result
        当浏览器第一次访问这个带有<s:token>标签的页面时,在服务器中,解析<s:token>标签的类(TokenTag.class),会生成一个随机的字符串(这个字符串,查看网页的源代码可以看到),并且发送给客户端的浏览器,同时,在服务器中,会把这个随机字符串保存到用户的session对象中。当第一次提交表单时,在服务器中,会比较客户端和服务器中分别保存的这个随机字符串,因为是第一次提交,所以这两个字符串相等,然后进行正常的业务处理。第一次提交后,在服务器中的session中保存的这个随机字符串,会改变为其他的随机值,注意,这是很重要的一步!此时,地址栏停留在处理用户提交数据的Action中,客户端中保存的随机字符串没有改变,若是刷新页面,即重复提交,服务器再进行两个字符串的比较,会不相等,就会跳转到name为invalid.token的结果页面中,这样就会防止表单重复提交了。

2.Token拦截器与TokenSession拦截器

  • 都是解决表单重复提交问题的
  •  使用token拦截器会转到token.valid的result
  •  使用tokenSession拦截器则还会响应那个目标页面,但不会执行tokenSession拦截器后续拦截器
  • Token 拦截器在遇到重复提交情况时, 会返回 invalid.token 结果并加上一个 Action 错误. 这种错误默认的消息是: The form has already been processed or no token was supplied, please try again.
  •  TokenSession 拦截器采取的做法只是阻断后续的提交, 用户将看到同样的响应,但实际上并没有重复提交

3.可以使用s:actionerror标签来显示提交表单重复的错误信息,该错误可以在国际化资源文件中覆盖,可以在struts-message-propertirs显示