Preface
In web development, preventing users from submitting forms repeatedly is a common requirement. Users may click the submit button multiple times due to network delays, misoperation, etc., causing the background to receive multiple identical requests. This will not only waste server resources, but may also lead to problems such as data inconsistency. This article will introduce several methods to implement interface anti-repeated submission in Spring Boot.
Use the Token mechanism
The Token mechanism is a common anti-repetition method. The specific steps are as follows:
Generate token: Each time the user requests a form page, the server generates a unique token and stores it in the Session.
Pass token: Embed the token into the form and submit it with the form.
Verify token: After the server receives the request, it first verifyes whether the token is valid. If it is valid, continue to process the request and remove the token from the Session; if it is invalid, an error message is returned.
Implementation steps
1. Generate tokens
Generate tokens in Controller and store them in Session:
/** * form * @param session * @author senfel * @date 2024/11/12 11:29 * @return */ @GetMapping("/form") public ModelAndView showForm(HttpSession session) { ModelAndView form = new ModelAndView("form"); String token = ().toString(); ("token", token); ("token", token); return form; }
2. Pass token
Add hidden fields to the form to pass the token:
<form action="/base/submit" method="post"> <input type="hidden" name="token" th:value="${token}"> <!-- Other form fields --> <button type="submit">Submit</button> </form>
3. Verify Token
Verify the token in Controller:
/** * handleForm * @param token * @param session * @author senfel * @date 2024/11/12 11:34 * @return */ @PostMapping("/submit") public String handleForm(@RequestParam String token, HttpSession session) { String sessionToken = (String) ("token"); if (sessionToken == null || !(token)) { throw new RuntimeException("Duplicate submit detected"); } // Remove Token ("token"); // Process form data return "success"; }
Using Redis
Redis is a high-performance key-value storage system that can be used to store and verify tokens. The specific steps are as follows:
Generate token: Each time the user requests a form page, the server generates a unique token and stores it in Redis.
Pass token: Embed the token into the form and submit it with the form.
Verify token: After the server receives the request, it first verifies whether the token exists in Redis. If it exists, continue to process the request and delete the token from Redis; if it does not exist, an error message is returned.
Implementation steps
1. Introduce Redis dependencies
Add Redis dependencies in :
<dependency> <groupId></groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2. Generate tokens
Generate tokens in Controller and store them in Redis:
@Autowired private StringRedisTemplate redisTemplate; /** * formByRedis * @author senfel * @date 2024/11/12 11:50 * @return */ @GetMapping("/formByRedis") public ModelAndView showFormByRedis() { ModelAndView form = new ModelAndView("form"); String token = ().toString(); // Set expiration time ().set(token, token, 5, ); ("token", token); return form; }
3. Pass token
Add hidden fields to the form to pass the token:
<form action="/base/submitByRedis" method="post"> <input type="hidden" name="token" th:value="${token}"> <!-- Other form fields --> <button type="submit">Submit</button> </form>
4. Verify Token
Verify the token in Controller:
/** * submitByRedis * @param token * @author senfel * @date 2024/11/12 11:50 * @return */ @PostMapping("/submitByRedis") public String handleFormByRedis(@RequestParam String token) { String redisToken = ().get(token); if (redisToken == null) { throw new RuntimeException("Duplicate submit detected"); } // Delete Token (token); // Process form data return "success"; }
Using Spring AOP
Spring AOP (Aspect-Oriented Programming) can be used to implement aspect programming, thereby reusing the logic against repeated commits in multiple methods.
Implementation steps
1. Definition annotation
Create a custom annotation @PreventDuplicateSubmit:
import ; import ; import ; import ; /** * PreventDuplicateSubmit * @author senfel * @date 2024/11/12 11:56 */ @Target() @Retention() public @interface PreventDuplicateSubmit { /**Repeat request time*/ int expireSeconds() default 10; }
2. Create a facet
Create a section class DuplicateSubmitAspect:
import .slf4j.Slf4j; import ; import ; import ; import ; import org.; import org.; import ; import ; import ; import ; import ; /** * DuplicateSubmitAspect * @author senfel * @version 1.0 * @date 2024/11/12 11:57 */ @Slf4j @Aspect @Component public class DuplicateSubmitAspect { protected static final Logger logger = (); @Autowired private StringRedisTemplate redisTemplate; /** * around * @param joinPoint * @author senfel * @date 2024/11/12 15:45 * @return */ @Around("@annotation()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { StringBuilder key = new StringBuilder(); //Get class String simpleName = ().getClass().getSimpleName(); (simpleName); // Get the request method MethodSignature signature=(MethodSignature)(); Method method = (); String methodName = (); (":").append(methodName); //Get request parameters Object[] args=(); for (Object arg : args) { (":").append(()); } //TODO Get client IP // Get annotation information PreventDuplicateSubmit annotation = (); // Determine whether the request has been requested if((())){ throw new RuntimeException("Do not repeat submission"); } //The mark request has been processed ().set((),"1",(), ); return (); } }
3. Use annotations
Use @PreventDuplicateSubmit annotation on the Controller method:
/** * handleFormByAnnotation * @param param * @author senfel * @date 2024/11/12 11:59 * @return */ @PostMapping("/submitByAnnotation") @PreventDuplicateSubmit public String handleFormByAnnotation(@RequestParam String param) { // Process form data return "success"; }
Summarize
This article introduces three ways to implement interface anti-repeated submission in Spring Boot: using the Token mechanism, using Redis, and using Spring AOP. Each method has its applicable scenarios and advantages and disadvantages, and you can choose the appropriate method according to actual needs. Through these methods, users can effectively prevent repeated submission of forms and improve system stability and user experience.
The above is the detailed content of the three solutions for SpringBoot interface anti-repeated submission. For more information about SpringBoot interface anti-repeated submission, please pay attention to my other related articles!