Using SpringMVC Interceptor to Prevent Duplicate Submissions
This article explains how duplicate form submissions occur, outlines common prevention techniques such as token validation and timestamp checks, and demonstrates a practical SpringMVC interceptor implementation with token storage and scheduled cleanup to ensure request uniqueness and reduce server load.
Introduction
Duplicate submissions happen when a user unintentionally sends the same request multiple times, leading to data inconsistency, resource waste, and performance degradation.
Common Prevention Techniques
Typical solutions include token validation, expiration timestamps, and database record checks, all of which aim to guarantee that a request can be processed only once within a certain time window.
Using an Interceptor to Prevent Duplicate Submissions
The following example shows a simple DuplicateSubmitInterceptor that stores received tokens in a Set<String> . If a token already exists, the interceptor blocks the request.
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashSet;
import java.util.Set;
public class DuplicateSubmitInterceptor implements HandlerInterceptor {
/**
* Store tokens
**/
private Set
tokens = new HashSet<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getParameter("token"); // get token from request
if (token != null) {
if (tokens.contains(token)) {
// token already exists, reject duplicate request
return false;
}
// otherwise, add token to the set
tokens.add(token);
}
return true;
}
}This interceptor checks the incoming token; if it has been seen before, the request is rejected, otherwise the token is stored for future checks.
Scheduled Cleanup of Expired Tokens
To avoid memory overflow caused by an ever‑growing token set, a scheduled task can periodically remove expired tokens. The example below adds a @Scheduled method that runs every 30 minutes.
@Component
public class DuplicateSubmitInterceptor implements HandlerInterceptor {
private Set
tokens = new HashSet<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getParameter("token");
if (token != null) {
if (tokens.contains(token)) {
return false;
}
tokens.add(token);
}
return true;
}
@Scheduled(fixedRate = 1800000) // every 30 minutes
public void cleanUpExpiredTokens() {
long currentTime = System.currentTimeMillis();
tokens.removeIf(token -> isTokenExpired(token, currentTime));
}
private boolean isTokenExpired(String token, long currentTime) {
// Assume token stores its creation time as a long value
long tokenCreationTime = Long.parseLong(token);
long tokenExpirationTime = tokenCreationTime + TimeUnit.MINUTES.toMillis(30);
return currentTime > tokenExpirationTime;
}
}The cleanUpExpiredTokens method removes tokens whose simulated creation time plus a 30‑minute TTL is older than the current time, preventing memory leaks.
Conclusion
Placing duplicate‑submission checks in a SpringMVC interceptor keeps the validation logic separate from controller and service layers, aligns with MVC separation of concerns, and can be enhanced with scheduled cleanup or external stores like Redis for scalability.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.