Disclaimer: This article belongs to reprint, transfer from blog: http://www.cnblogs.com/xdp-gacl/p/3859416.html
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.
I. Common application scenarios for form repeat submissions
Like the next form.jsp page
1 <%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%> 2 <! DOCTYPE html> 3
Form form submitted to doformservlet for processing
1 package xdp.gacl.session; 2 3 Import java.io.IOException; 4 Import javax.servlet.ServletException; 5 Import Javax.servlet.http.HttpServlet; 6 Import Javax.servlet.http.HttpServletRequest; 7 Import Javax.servlet.http.HttpServletResponse; 8 9 public class Doformservlet extends HttpServlet {ten public void doget (HttpServletRequest request, Httpservletre Sponse response) throws Servletexception, IOException {13//client is transmitting data in UTF-8 encoding to the server side, so it is necessary to set the server side to UTF-8 Code to receive, otherwise the Chinese data will produce garbled request.setcharacterencoding ("UTF-8"); String userName = Request.getparameter ("U Sername "); try {17//To allow the current thread to sleep for 3 seconds, simulating a network delay causing the form to repeat the behavior of Thread.Sleep (3*1000); 19} catch (Interruptedexception e) {e.printstacktrace ();}22 System.out.println ("Insert data into database:" + UserName);}24 public void DoPost (HttpServletRequest request, httpservletresponse response) THR oWS Servletexception, Ioexception {doget (request, response); 28}29 30}
If you do not repeat the form form, the following actions will cause the form form to repeat multiple times in case of network delay
1.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, causing 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, scene Three: After the user submits the form, click the browser's "Back" button back to the form page to submit againThe demo animation looks like this:
Ii. using JavaScript to prevent forms from repeating submissionsSince 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
1 <%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%> 2 <! DOCTYPE html> 3
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:
1 function Dosubmit () {2 //Get Form Submit button 3 var btnsubmit = document.getElementById ("submit"); 4 //Set Form Submit button to unavailable , so that you can avoid the user to click the Submit button again 5 btnsubmit.disabled= "disabled"; 6 //Returns True to allow the form to submit 7 return true;8}
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
1 package xdp.gacl.session; 2 3 Import java.io.IOException; 4 Import javax.servlet.ServletException; 5 Import Javax.servlet.http.HttpServlet; 6 Import Javax.servlet.http.HttpServletRequest; 7 Import Javax.servlet.http.HttpServletResponse; 8 9 public class Formservlet extends HttpServlet {Ten private static final long Serialversionuid = 884689940866074733 l;11 public void doget (HttpServletRequest request, httpservletresponse response) throws Servletexcept Ion, IOException {String token = tokenproccessor.getinstance (). Maketoken ();//Create Token System.out.print ln ("token generated in Formservlet:" +token); Request.getsession (). SetAttribute ("token", token); The server uses session to save tokens (tokens) request.getrequestdispatcher ("/form.jsp"). Forward (request, response);// Jump to form.jsp page}20 public void DoPost (HttpServletRequest request, httpservletresponse response) 22 Throws Servletexception, IOException {doget (request, REsponse); 24}25 26}
2. Use hidden fields in form.jsp to store tokens (tokens)
1 <%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%> 2 <! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" > 3
3.DoFormServlet Processing Form Submission
1 package xdp.gacl.session; 2 3 Import java.io.IOException; 4 Import javax.servlet.ServletException; 5 Import Javax.servlet.http.HttpServlet; 6 Import Javax.servlet.http.HttpServletRequest; 7 Import Javax.servlet.http.HttpServletResponse; 8 9 public class Doformservlet extends HttpServlet {ten public void doget (HttpServletRequest request, Httpservletre Sponse response) throws Servletexception, IOException {a Boolean b = Isrepeatsubmit (requ EST);//Determine if the user is repeating the b==true {System.out.println ("Do not repeat Submissions"); return;18 }19 request.getsession (). RemoveAttribute ("token");//Remove Token20 System.out.pri in session NTLN ("Process user submit Request!! 21}22 23/**24 * Determine if the token that is submitted by the client is consistent with the server-side generated token * @param request26 * @return * True user repeatedly submits form * False user did not submit form */30 private Boolea N isrepeatsUbmit (HttpServletRequest request) {String Client_token = Request.getparameter ("token"); 32//1, as If there is no token in the form data submitted by the user, the user submits the form in duplicate (client_token==null) {return true;35}36 Remove the token37 String Server_token = (string) request.getsession () stored in the session. GetAttribute ("token"); 38 2. If token (token) is not present in the session of the current user, the user is repeatedly submitting the form, if (server_token==null) { ; 41}42//3, token (token) stored in the session is different from the token (token) submitted by the form, then the user submits the form in duplicate if (!client_token.equa LS (server_token)) {true;45}46 return false;48}49 public void DoPost (HttpServletRequest request, httpservletresponse response) Wuyi throws Servletexception , IOException {doget (request, response); 53}54 55}
Tool class for token generation Tokenproccessor
1 package xdp.gacl.session; 2 3 Import Java.security.MessageDigest; 4 Import java.security.NoSuchAlgorithmException; 5 Import Java.util.Random; 6 Import Sun.misc.BASE64Encoder; 7 8 public class Tokenproccessor {9 10/*11 * Singleton design mode (guarantees that the class object is only one in memory) 12 * 1, the constructor of the class is private 13 * 2, and you create a class object 14 * 3. Provide a public method to return the object of class */16 private Tokenproccessor () {}17 private static final tokenproccessor I Nstance = new Tokenproccessor (); 19 20/**21 * Returns the object of the class. * @return23 */24 public static Tokenproc Cessor getinstance () {return instance;26}27 28/**29 * Generate TOKEN30 * token:nv6rrugevvmgjb+j IMI/GW==31 * @return32 */33 public String Maketoken () {//checkexception34//7346734837483 834u93 8493493849384 4343438435 String token = (System.currenttimemillis () + new Random (). Nextint (999999999)) + ""; 36 Data fingerprint 128 bits long 16 bytes md537 try {messagedigest MD = MESSAGEdigest.getinstance ("MD5"); ("md5[") = Md.digest (Token.getbytes ());//base64 encoding-any binary encoded text character adfsdfsdfsf41 Base64encoder encoder = new Base64encoder (); return Encoder.encode (MD5); 43 } catch (NoSuchAlgorithmException e) {runtimeexception throw new (e); 45}46}47}
First access to the Formservlet, in the Formservlet to generate tokens and then redirect to the form.jsp page, this time in the server-side processing form repeated submissions, the performance is as follows:
From the running effect can be seen, this way to deal with the form of repeated submissions, you can solve the above scenario two and scenario three in the form of duplicate submission problems.
[Java Supplements v] Use the session to prevent the form from repeating the submission