Reprint Please specify source: http://blog.csdn.net/l1028386804/article/details/45968185
In peacetime development, if the network speed is slow, the user submits the form, found that the server has not responded to a half-day, then the user may think that they did not submit the form, then click the Submit button to repeat the form, we must prevent the form of duplicate submissions in development.
One, the form of repeated submissions of the scene
Like the next form.jsp page
<%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%><! DOCTYPE html>
Form form submitted to DoformservletPackage Xdp.gacl.session;import Java.io.ioexception;import Javax.servlet.servletexception;import Javax.servlet.http.httpservlet;import Javax.servlet.http.httpservletrequest;import Javax.servlet.http.httpservletresponse;public class Doformservlet extends HttpServlet {public void doget (HTTPSERVLETR Equest request, HttpServletResponse response) throws Servletexception, IOException {//client is transmitting data in UTF-8 encoding to Server-side, so you need to set up the server to UTF-8 code to receive, otherwise the Chinese data will produce garbled request.setcharacterencoding ("UTF-8"); String userName = Request.getparameter ("UserName"); try {//causes the current thread to sleep for 3 seconds, simulating network latency and causing the form to repeat the phenomenon Thread.Sleep (3*1000); } catch (Interruptedexception e) {e.printstacktrace (); } System.out.println ("Insert data into Database:" +username); } public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioex ception {doget (request, response); }}
If you do not repeat the form form, the following actions will cause the form form to repeat multiple times in case of network delay1.1 Scene One, in the case of network delay, let the user have time to click Multiple Submit button to cause the form to repeat the submissionThe demo animation looks like this:
1.2, scene Two: After the form is submitted, the user clicks the "refresh button" to cause the form to repeat the submissionThe demo animation looks like this:
Click the Browser refresh button to do the last thing the browser did again, because this will also cause the form to repeat the submission.
1.3: After the user clicks the Submit button, click the "Back button" of the browser to fall back to the submission page of the form page and submit again.The demo animation looks like this:
Ii. using JavaScript to prevent forms from repeating submissions
Since there is the above-mentioned form of duplicate submission problem, then we have to find a way to solve, more commonly used is to use JavaScript to prevent the form of repeated submissions, as follows:
Modify the Form.jsp page and add the following JavaScript code to prevent the form from repeating the submission.
<%@ page Language= "java" import= "java.util.*" pageencoding= "UTF-8"%><! DOCTYPE html>
Let's look at the use of JavaScript to prevent form submission duplication from succeeding, and run the effect as follows:
As you can see, using JavaScript is the solution to the scenario where the user has time to click the Submit button multiple times in the event of a network delay , and it solves the problem . Control form forms with JavaScript can only be submitted once .
In addition to this approach, another common way is when the form is submitted, the Submit button is set to unavailable, so that the user does not have the opportunity to click the Second Commit button, the code is as follows:
function Dosubmit () { //Get Form Submit Button var btnsubmit = document.getElementById ("submit"); Set the form Submit button to be unavailable, so you can avoid the user clicking the Submit button again btnsubmit.disabled= "disabled"; Returns true to allow the form to commit normally return true;}
The results are as follows:
Another way is to submit the form, the submission button is hidden, this practice and the Submit button is set to not be available is similar to, the personal feel that the submit button hiding affects the layout of the page beautiful, and may make the user mistakenly think it is a bug (how can I click the button, the button is gone?) The user may have this question), I personally in the development of the use of more than the form is submitted, the Submit button is set to not be available, anyway, using JavaScript to prevent the form of repeated submissions is similar, the purpose is to make the form can only be submitted once, so that the form can not be repeated submissions.
The practice of using JavaScript to prevent forms from repeating submissions is only valid for scenario one in the three scenarios above that resulted in repeated submissions of forms, and for scene two and scene three, it is still not possible to resolve the form repeat submission problem.
Third, use the session to prevent the form repeating the submissionFor "Scene two" and "scene three" caused the form to repeat the problem, since the client cannot resolve, then the server-side solution, the server-side solution will need to use the session.
How to do this: Generate a unique random identification number on the server side, a professional term called token (token), and save the token in the current user's session field. The token is then sent to the client's form form, using a hidden field in the form form to store the token, which is submitted to the server side with the token, Then on the server side to determine whether the client submitted tokens and server-side generated token is consistent, if not consistent, it is repeated commit, the server side can not process the duplicate submission of the form. If the same is done, the form submission is processed and the identification number stored in the session field of the current user is cleared.
The server program will refuse to process a user-submitted form request in the following cases:
- Tokens ( tokens) in the stored session domain are different from the tokens (tokens) submitted by the form.
- Token (token)does not exist in the current user's session.
- There is no token (token)in the form data submitted by the user.
Look at the specific example:
1. Create Formservlet to generate tokens (tokens) and jump to form.jsp pages
Package Xdp.gacl.session;import Java.io.ioexception;import Javax.servlet.servletexception;import Javax.servlet.http.httpservlet;import Javax.servlet.http.httpservletrequest;import javax.servlet.http.httpservletresponse;/** * Author Liuyazhuang */public class Formservlet extends HttpServlet {Priva Te static final long serialversionuid = -884689940866074733l; public void doget (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioexceptio n {String token = tokenproccessor.getinstance (). Maketoken ();//Create a token System.out.println ("Toke generated in Formservlet N: "+token"); Request.getsession (). SetAttribute ("token", token); The server uses the session to save tokens (tokens) request.getrequestdispatcher ("/form.jsp"). Forward (request, response);//Jump to form.jsp page } public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioex ception {doget (request, response); }}
2. Use hidden fields in form.jsp to storeToken (tokens)
<%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%><! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" >
3.DoFormServlet Processing Form SubmissionPackage Xdp.gacl.session;import Java.io.ioexception;import Javax.servlet.servletexception;import Javax.servlet.http.httpservlet;import Javax.servlet.http.httpservletrequest;import javax.servlet.http.httpservletresponse;/** * Author Liuyazhuang */public class Doformservlet extends HttpServlet {pub LIC void doget (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioexcepti on {Boolean b = isrepeatsubmit (request);//Determine if the user is repeating commit if (b==true) {System.out.printl N ("Please do not repeat the submission"); Return } request.getsession (). RemoveAttribute ("token");//Remove token System.out.println in session ("Process user submit Request!! "); /** * Determine if the token generated by the client is consistent with the server-side tokens * @param request * @return * TR The UE user submits the form repeatedly * False the user does not submit the form repeatedly */private Boolean isrepeatsubmit (HttpServletRequest reque ST) {String client_tOken = Request.getparameter ("token"); 1. If there is no token in the form data submitted by the user, the user is repeatedly submitting the form if (Client_token==null) {return true; }//Remove token String Server_token = (string) request.getsession () stored in session. GetAttribute ("token"); 2. If token (token) does not exist in the session of the current user, the user is repeatedly submitting the form if (Server_token==null) {return true; }//3, token (token) stored in the session is different from the token (token) submitted by the form, and the user is repeatedly submitting the form if (!client_token.equals (Server_toke N)) {return true; } return false; } public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioex ception {doget (request, response); }}
Tool class for token generationTokenproccessor
Package Xdp.gacl.session;import Java.security.messagedigest;import Java.security.nosuchalgorithmexception;import Java.util.random;import sun.misc.base64encoder;/** * Author Liuyazhuang */public class Tokenproccessor {/* * Single case Design model (The object of the class is guaranteed to have only one in memory) * 1, the constructor of the class is private * 2, you create an object of a class, you provide a public method, return the object of the class */Private Tokenproccessor () {} Private static final Tokenproccessor instance = new Tokenproccessor (); /** * Returns the object of the class * @return */public static tokenproccessor getinstance () {return instance; }/** * Generates Token * token:nv6rrugevvmgjb+jimi/gw== * @return */public String Maketoken () {//CHEC Kexception//7346734837483 834u938493493849384 43434384 String token = (System.currenttimemillis () + new Random (). Nextint (999999999)) + ""; Data fingerprint 128 bits long 16 bytes MD5 try {messagedigest MD = messagedigest.getinstance ("MD5"); byte md5[] = Md.digest (Token.getbytes ()); Base64 encoding--arbitrary binary encoded text character ADFSDFSDFSF Base64encoder encoder = new Base64encoder (); Return Encoder.encode (MD5); } catch (NoSuchAlgorithmException e) {throw new RuntimeException (e); } }}
First visit Formservlet, generate tokens in the Formservlet and then redirect to the form.jsp page, this time on the server side processing form repeated submissions,
This way of processing the form duplicate commits, can solve the above scenario two and scenario three appear in the form of duplicate submission problem.
Javaweb--Use the session to prevent the form from repeating the submission (episode)