The common problem is browser submitting same request on refresh or ctrl+f5. To overcome the issue in java we have to write token implementation, this is similar to what Struts framework provides.
Common Token Class
package com.nmmc.common.utils;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class CommonTokenUtils
{
public static String TOKEN_KEY = Constants.SESSION_TOKEN_KEY;
public static String TOKEN_VALUE = "";
private static synchronized boolean isTokenValid(HttpSession session, String requestToken) throws Exception {
String sessionToken = (String)session.getAttribute(getTokenKey());
if (requestToken == null) {
// The hidden field wasn't provided
throw new Exception("Missing synchronizer token in request");
}
if (sessionToken == null) {
// The session has lost the token.
throw new Exception("Missing synchronizer token in session");
}
if (sessionToken.equals(requestToken)) {
// Accept the submission and increment the token so this form can't
// be submitted again ...
TOKEN_VALUE=nextToken();
session.setAttribute(getTokenKey(), TOKEN_VALUE);
return true;
}
return false;
}
private static String nextToken() {
long seed = System.currentTimeMillis();
Random r = new Random();
r.setSeed(seed);
return Long.toString(seed) + Long.toString(Math.abs(r.nextLong()));
}
private static String getTokenKey() {
return TOKEN_KEY;
}
public static void setNewToken(HttpServletRequest request)
{
HttpSession session = request.getSession();
TOKEN_VALUE=nextToken();
session.setAttribute(getTokenKey(), TOKEN_VALUE);
}
public static void setNewToken(HttpSession session)
{
TOKEN_VALUE=nextToken();
session.setAttribute(getTokenKey(), TOKEN_VALUE);
}
public static boolean allowFormSubmit(HttpServletRequest request)
{
try {
HttpSession session = request.getSession();
String requestToken = request.getParameter(getTokenKey());
if(isTokenValid(session, requestToken))
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static boolean allowFormSubmit(HttpSession session, String requestToken)
{
try {
if(isTokenValid(session, requestToken))
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
Client Code in Controller:
if (CommonTokenUtils.allowFormSubmit(request)){
// Allow save or update
}
//reset the token to avoid duplicate submission
CommonTokenUtils.setNewToken(request);
Common Token Class
package com.nmmc.common.utils;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class CommonTokenUtils
{
public static String TOKEN_KEY = Constants.SESSION_TOKEN_KEY;
public static String TOKEN_VALUE = "";
private static synchronized boolean isTokenValid(HttpSession session, String requestToken) throws Exception {
String sessionToken = (String)session.getAttribute(getTokenKey());
if (requestToken == null) {
// The hidden field wasn't provided
throw new Exception("Missing synchronizer token in request");
}
if (sessionToken == null) {
// The session has lost the token.
throw new Exception("Missing synchronizer token in session");
}
if (sessionToken.equals(requestToken)) {
// Accept the submission and increment the token so this form can't
// be submitted again ...
TOKEN_VALUE=nextToken();
session.setAttribute(getTokenKey(), TOKEN_VALUE);
return true;
}
return false;
}
private static String nextToken() {
long seed = System.currentTimeMillis();
Random r = new Random();
r.setSeed(seed);
return Long.toString(seed) + Long.toString(Math.abs(r.nextLong()));
}
private static String getTokenKey() {
return TOKEN_KEY;
}
public static void setNewToken(HttpServletRequest request)
{
HttpSession session = request.getSession();
TOKEN_VALUE=nextToken();
session.setAttribute(getTokenKey(), TOKEN_VALUE);
}
public static void setNewToken(HttpSession session)
{
TOKEN_VALUE=nextToken();
session.setAttribute(getTokenKey(), TOKEN_VALUE);
}
public static boolean allowFormSubmit(HttpServletRequest request)
{
try {
HttpSession session = request.getSession();
String requestToken = request.getParameter(getTokenKey());
if(isTokenValid(session, requestToken))
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static boolean allowFormSubmit(HttpSession session, String requestToken)
{
try {
if(isTokenValid(session, requestToken))
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
Client Code in Controller:
if (CommonTokenUtils.allowFormSubmit(request)){
// Allow save or update
}
//reset the token to avoid duplicate submission
CommonTokenUtils.setNewToken(request);