Javaweb---summary (13) Use the session to prevent forms from repeating submissions

Source: Internet
Author: User

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

<%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%>

<! DOCTYPE html>

<title>form form </title>

<body>

<form action= "${pagecontext.request.contextpath}/servlet/doformservlet" method= "post" >

User name: <input type= "text" name= "username" >

<input type= "submit" value= "submitted" id= "submission" >

</form>

</body>

Form form submitted to doformservlet for processing

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;

public class Doformservlet extends HttpServlet {

public void Doget (httpservletrequest request, httpservletresponse Response)

Throws servletexception, IOException {

The client is UTF-8 encoded data to the server side, so you need to set the server side to UTF-8 encoding to receive, otherwise the Chinese data will be 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 repeatedly commit

Thread.Sleep (3*1000);

} catch (interruptedexception E) {

E.printstacktrace ();

}

SYSTEM.OUT.PRINTLN ("inserting data into the database:" +username);

}

public void DoPost (httpservletrequest request, httpservletresponse Response)

Throws servletexception, IOException {

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 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 submission

The 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 submission

The 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 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>

<title>form form </title>

<script type= "text/javascript" >

var iscommitted = False;//whether The form has been submitted for identification, default to False

function Dosubmit () {

If (iscommitted==false) {

iscommitted = True;//the form is submitted after the form has been submitted, the identity is set to True

Return true;//returns true to allow form to be submitted normally

}else{

Return false;//returns false so the form will not commit

}

}

</script>

<body>

<form action= "${pagecontext.request.contextpath}/servlet/doformservlet" onsubmit= "return dosubmit ()" method= " Post ">

User name: <input type= "text" name= "username" >

<input type= "submit" value= "submitted" id= "submission" >

</form>

</body>

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 not be available so that you can prevent users from clicking the Submit button again

Btnsubmit.disabled= "disabled";

Returns true to allow the form to be submitted normally

Return true;

}

The results are as follows:

Motion diagram

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 submission

For "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:

    1. Tokens ( TOKENS) in the stored session domain are different from the tokens (tokens) submitted by the FORM.

    2. Token (token)does not exist in the current User's Session.

    3. 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;

public class Formservlet extends HttpServlet {

Private static final Long Serialversionuid = -884689940866074733l;

public void Doget (httpservletrequest request, httpservletresponse Response)

Throws servletexception, IOException {

String token = tokenproccessor.getinstance (). maketoken ();//create Token

System.out.println ("tokens generated in formservlet:" +token);

Request.getsession (). SetAttribute ("token", token); Save tokens (TOKENS) in the server using session

Request.getrequestdispatcher ("/form.jsp"). forward (request, response);//jump to form.jsp page

}

public void DoPost (httpservletrequest request, httpservletresponse Response)

Throws servletexception, IOException {

Doget (request, response);

}

}

2. Use hidden fields in form.jsp to store tokens (tokens)

<%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%>

<! DOCTYPE HTML public "-//w3c//dtd HTML 4.01 transitional//en" >

<title>form form </title>

<body>

<form action= "${pagecontext.request.contextpath}/servlet/doformservlet" method= "post" >

<%--generated token--%> using hidden domain storage

<%--

<input type= "hidden" name= "token" value= "<%=session.getattribute (" token ")%>" >

--%>

<%--using El expression to remove token--%> stored in session

<input type= "hidden" name= "token" value= "${token}"/>

User name: <input type= "text" name= "username" >

<input type= "submit" value= "submission" >

</form>

</body>

3.DoFormServlet Processing Form Submission

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;

public class Doformservlet extends HttpServlet {

public void Doget (httpservletrequest request, httpservletresponse Response)

Throws servletexception, IOException {

Boolean B = Isrepeatsubmit (request);//determine If the user is repeating the commit

If (b==true) {

System.out.println ("please do not repeat submissions");

Return

}

Request.getsession (). removeattribute ("token");//remove token from session

System.out.println ("process User Submit request!! ");

}

/**

* Determine whether the token generated by the client and the Server-side token are consistent

* @param request

* @return

* True user submits the form repeatedly

* False user does not submit form repeatedly

*/

Private Boolean Isrepeatsubmit (httpservletrequest Request) {

String Client_token = Request.getparameter ("token");

1. If there is no token in the form data submitted by the user, the user submits the form repeatedly

If (client_token==null) {

Return true;

}

Take out tokens stored in the session

String server_token = (string) request.getsession (). getattribute ("token");

2. If token (token) does not exist in the current User's session, the user submits the form repeatedly

If (server_token==null) {

Return true;

}

3. Tokens stored in the session are different from tokens (TOKENS) submitted by the form, and the user submits the form repeatedly

If (!client_token.equals (SERVER_TOKEN)) {

Return true;

}

Return false;

}

public void DoPost (httpservletrequest request, httpservletresponse Response)

Throws servletexception, IOException {

Doget (request, response);

}

}

Tool class for token generation Tokenproccessor

Package xdp.gacl.session;

Import java.security.MessageDigest;

Import java.security.NoSuchAlgorithmException;

Import java.util.Random;

Import sun.misc.BASE64Encoder;

public class Tokenproccessor {

/*

* Singleton design mode (guaranteed that the class object is only one in Memory)

* 1, the constructor of the class is private

* 2. Create a Class object yourself

* 3. Provide a public method to 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;

}

/**

* Token generation

* token:nv6rrugevvmgjb+jimi/gw==

* @return

*/

Public String Maketoken () {//checkexception

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,

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.

Javaweb---summary (13) Use the session to prevent forms from repeating submissions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.