template exe exception soft con message pac ucc request
struts2防表单重复提交有两种方式。
其一是action的重定向,跳转时设置type为从一个action跳转到另一个action或者另一个页面,
使用户提交后,所停留的位置,不是当前处理数据的Action,这样用户再刷新时,就不会再次执行这个Action了,
就会避免表单重复提交的问题了。
其二就是session令牌的方式(token)
处理也很方便,只需要在所提交的表单上加一个struts2标签 <s:token>
注意在该页面需要导入 <%@taglib prefix="s" uri="/struts-tags"%>
这样,当浏览器第一次访问这个带有<s:token>标签的页面时,在服务器中,解析<s:token>标签的类(TokenTag.class),
会生成一个随机的字符串(这个字符串,查看网页的源代码可以看到),并且发送给客户端的浏览器,同时,在服务器中,
会把这个随机字符串保存到用户的session对象中。
当第一次提交表单时,在服务器中,会比较客户端和服务器中分别保存的这个随机字符串,因为是第一次提交,
所以这两个字符串相等,然后进行正常的业务处理。第一次提交后,在服务器中的session中保存的这个随机字符串,
会改变为其他的随机值,注意,这是很重要的一步!此时,地址栏停留在处理用户提交数据的Action中,
客户端中保存的随机字符串没有改变,若是刷新页面,即重复提交,服务器再进行两个字符串的比较,
会不相等,就会跳转到name为invalid.token的结果页面中,这样就会防止表单重复提交了。
贴上示例代码
struts_regist.jsp
- <%@ taglib prefix="s" uri="/struts-tags" %>
- <%--
- Created by IntelliJ IDEA.
- User: leslie
- Date: 17-12-2
- Time: 上午10:46
- To change this template use File | Settings | File Templates.
- --%>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>注册</title>
- </head>
- <body>
- <form action="${pageContext.request.contextPath}/struts_regist" method="post">
- <s:token />
- 用户名:<input type="text" name="name"><br>
- 密 码:<input type="password" name="password"><br>
- <input type="submit" value="注册">
- </form>
- </body>
- </html>
struts.xml
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration
- 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
- <struts>
- <package name="default" namespace="/" extends="struts-default">
- <action name="regist" class="cn.itcast.action.RegistAction">
- <result name="invalid.token">
- /token.jsp
- </result>
- <interceptor-ref name="token" />
- <interceptor-ref name="defaultStack" />
- </action>
- </package>
- </struts>
token.jsp
- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
- <%@taglib prefix="s" uri="/struts-tags"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>My JSP ‘index.jsp‘ starting page</title>
- </head>
- <body>
- <s:actionerror/>
- </body>
- </html>
RegistAction
- package com.emuii.action;
- import com.opensymphony.xwork2.ActionSupport;
- import org.apache.struts2.ServletActionContext;
- public class RegistAction extends ActionSupport {
- @Override public String execute() throws Exception {
- String name = ServletActionContext.getRequest().getParameter("name");
- String password = ServletActionContext.getRequest().getParameter("password");
- System.out.println(name + ":" + password + "已注册");
- return null;
- }
- }
如果想要自定义错误信息,只需在action同一目录下创建一个 ----类名.properties配置文件即可
RegistAction.properties
- 1 struts.messages.invalid.token = \u60A8\u5DF2\u7ECF\u91CD\u590D\u63D0\u4EA4\u8868\u5355\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5
另:对于只有一个action来说,通配符跳转的方式第一种防表单提交无效的,虽然重定向之后的jsp页面不一样。
如果需要对特定的方法进行防表单提交这样:
- <action name="someAction" class="com.examples.SomeAction">
- <interceptor-ref name="token">
- <param name="includeMethods">myMethod</param>
- </interceptor-ref name="token"/>
- <interceptor-ref name="basicStack"/>
- <result name="success">good_result.ftl</result>
- </action>
<param name="includeMethod">xx</param>表示只拦截xx方法
<param name="excludeMethod">xx</param>表示拦截xx方法之外的方法
另:WARN [org.apache.struts2.util.TokenHelper] - Could not find token name in params.出现这个问题,
也有可能是你没对指定方法进行拦截,当然情况不一定非是这种的,只是因为我的项目问题才导致这个问题的。
关于struts2防止表单重复提交
template exe exception soft con message pac ucc request
原文:http://www.cnblogs.com/lesliehe/p/7989560.html
来源: http://www.bubuko.com/infodetail-2418640.html