I am writing the DAO (data access objects) for our web application and it is not done yet. I have not plugged-in any data duplication prevention logic and that means you can have duplicate rows in database. Now, duplicate row prevention is a topic in itself and a lot of time you do not want to plug it in because duplicate prevention is time consuming task. Doing a column by column comparison on a large table may not perform very well. Anyways that is not the main story. Main story is, my data API allow duplicate rows, so if a user re-submits some form page by clicking refresh button then we insert a duplicate row in database quite unintentionally.
We are using struts framework for page flows. Page refresh calls the data flushing action again and we want to prevent that. I did a bit of goggling around and looks like everyone is using "synchronizer token pattern" to avoid this problem. The scheme is following:
When a page is requested, generate a token and render this token as part of the page. (maybe as a hidden field). Store this same token in session using the page as key. when the page is submitted, you compare the token from page to the one stored in session, if both of them match then allow submit. If submit is successful then clear the token from session (using page as key).
Now, lets say the user hits refresh. The page still has the old token, so the token from page would not match the token in session and we do not allow submits. If user requests that page again through normal work flow then we re-generate a new token and everything is okay dokay ;o) if I am not feeling very lazy i will try this pattern with a simple form and servlet.
We are using struts framework for page flows. Page refresh calls the data flushing action again and we want to prevent that. I did a bit of goggling around and looks like everyone is using "synchronizer token pattern" to avoid this problem. The scheme is following:
When a page is requested, generate a token and render this token as part of the page. (maybe as a hidden field). Store this same token in session using the page as key. when the page is submitted, you compare the token from page to the one stored in session, if both of them match then allow submit. If submit is successful then clear the token from session (using page as key).
Now, lets say the user hits refresh. The page still has the old token, so the token from page would not match the token in session and we do not allow submits. If user requests that page again through normal work flow then we re-generate a new token and everything is okay dokay ;o) if I am not feeling very lazy i will try this pattern with a simple form and servlet.
Struts has built in support for synchronizer tokens. Some useful links
- AJUG post
- solution for ASP.NET _ i have not looked at it myself
- Apache mailing list - avoid resubmit Thread
- Same thread, this post contains some code as well
- Tip 136 from java world with some actual code
- Google for synchronizer token pattern
- OnJava.com article for controlling multiple submits
- Craig McClanahan's response on archived on junlu
- Core J2EE patterns - look for Deja Vu or synchronizer