struts1 重复提交
2014-05-02 23:28
302 查看
Struts的Token机制能够很好的解决表单重复提交的问题,基本原理是:
服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。
在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。
这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
java代码:
jsp代码:
查看html源代码:
提交,回退,刷新页面:
多了一段html:
这是后来生成的,value值就是生成的token。
再次提交,token是合法的,此时不是重复提交。
提交后,回退,不刷新,再次提交,token就不合法了,此时就是重复提交。
看看相关代码,在org.apache.struts.util.TokenProcessor里:
服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。
在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。
这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
java代码:
package com.struts1.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.Globals; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class TokenAction extends Action { @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { if (isTokenValid(request)) { //回退,刷新,提交 System.out.println("resetToken"); resetToken(request); } else { String token = request.getParameter(Globals.TOKEN_KEY); if (token != null) { //重复提交。回退,提交 System.out.println("repeat submit"); } else { //第一次提交 System.out.println("first submit"); } saveToken(request); } return mapping.findForward("success"); } }
jsp代码:
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <%@ taglib uri="http://struts.apache.org/tags-nested" prefix="nested" %> <%@ page import="org.apache.struts.Globals" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>Insert title here</title> </head> <body> <html:form action="token.do" method="post"> <html:text property="username" /><br> <html:password property="password" /><br> <html:submit /> </html:form> </body> </html>
查看html源代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>Insert title here</title> </head> <body> <form name="tokenForm" method="post" action="/struts1-token/token.do"> <input type="text" name="username" value=""><br> <input type="password" name="password" value=""><br> <input type="submit" value="Submit"> </form> </body> </html>
提交,回退,刷新页面:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>Insert title here</title> </head> <body> <form name="tokenForm" method="post" action="/struts1-token/token.do"><div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="c9c68b8abd7ffd703245cc0dc5539af4"></div> <input type="text" name="username" value=""><br> <input type="password" name="password" value=""><br> <input type="submit" value="Submit"> </form> </body> </html>
多了一段html:
<div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="c9c68b8abd7ffd703245cc0dc5539af4"></div>
这是后来生成的,value值就是生成的token。
再次提交,token是合法的,此时不是重复提交。
提交后,回退,不刷新,再次提交,token就不合法了,此时就是重复提交。
看看相关代码,在org.apache.struts.util.TokenProcessor里:
public synchronized void saveToken(HttpServletRequest request) { HttpSession session = request.getSession(); String token = generateToken(request); if (token != null) { session.setAttribute(Globals.TRANSACTION_TOKEN_KEY, token); } }
public synchronized void resetToken(HttpServletRequest request) { HttpSession session = request.getSession(false); if (session == null) { return; } session.removeAttribute(Globals.TRANSACTION_TOKEN_KEY); }
public synchronized boolean isTokenValid(HttpServletRequest request) { return this.isTokenValid(request, false); } public synchronized boolean isTokenValid(HttpServletRequest request, boolean reset) { // Retrieve the current session for this request HttpSession session = request.getSession(false); if (session == null) { return false; } // Retrieve the transaction token from this session, and // reset it if requested String saved = (String) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY); if (saved == null) { return false; } if (reset) { this.resetToken(request); } // Retrieve the transaction token included in this request String token = request.getParameter(Globals.TOKEN_KEY); if (token == null) { return false; } return saved.equals(token); }
相关文章推荐
- Struts中防止任意形式的重复提交
- 使用Struts 2防止表单重复提交
- Struts解决重复提交问题
- 使用struts1回显数据,防重复提交
- 使用struts的同步令牌避免form的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 解决Struts重复提交的问题.
- jsp或struts如何避免Form重复提交,不然数据中的插入的纪录有重复的!
- 用Struts的Token机制解决表单重复提交
- Struts1防止表单重复提交
- struts 防止重复提交表单
- Struts重复提交
- Struts解决重复提交问题
- Struts中防止任意形式的重复提交
- <转>防止刷新/后退引起的重复提交问题的Java Token代码,非Struts
- 防止刷新/后退引起的重复提交问题的Java Token代码,非Struts
- struts--token防止表单重复提交(源码分析)
- strust2防止重复提交的struts.token的原理
- 如何使用Struts 2防止表单重复提交?
- 使用Struts实现防止表单重复提交