Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to combine SpringBoot with Aop+Redis to prevent repeated submission of APIs

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)05/31 Report--

Most people do not understand the knowledge of this article "how to combine SpringBoot with Aop+Redis to prevent repeated submission", so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "how to combine SpringBoot with Aop+Redis to prevent repeated submission" article.

In actual development projects, an exposed interface is often faced with many requests. Let's explain the idempotent concept: the impact of any number of execution is the same as that of a single execution. According to this meaning, the ultimate meaning is that the impact on the database can only be one-off, can not be repeated processing. How to ensure its idempotency, there are usually the following means:

1. The establishment of a unique index in the database can ensure that only one piece of data is finally inserted into the database.

2. Token mechanism: get a token before each API request, and then add the token to the header body of the request next time. The backend verifies it. If the verification passes the deletion of the token, the token is judged again in the next request.

3. Pessimistic lock or optimistic lock, pessimistic lock can guarantee that other sql cannot update data every time for update (when the database engine is innodb, the condition of select must be a unique index to prevent locking the whole table)

4. Query first and then judge. First, query whether the data exists in the database. If the existence proof has already been requested, reject the request directly. If it does not exist, it is proved to be the first time to come in and let it go directly.

Why prevent the interface from being repeatedly submitted?

For some sensitive operation interfaces, such as new data interfaces and payment interfaces, if users do not operate properly and click the submit button many times, these interfaces will be requested many times, which may eventually lead to system exceptions.

How can the front end be controlled?

The front end can be controlled by js, when the user clicks the submit button

1. How many seconds does the button set to be unclickable?

two。 Click the button and pop up the loading prompt box to avoid clicking again until the API request is returned.

3. Click the button and jump to a new page

But remember, never trust the user's behavior, because you don't know what weird actions the user will do, so the most important thing is to deal with it at the back end.

Use aop+redis for intercept processing

one。 Create a facet class RepeatSubmitAspect

Implementation process: after the API request, the token+ request path is used as the key value to read the data in the redis. If the key can be found, it is proved to be submitted repeatedly, and vice versa. If the submission is not repeated, release it directly, write the key to redis, and set it to expire for a certain period of time (the 5s expiration I set here)

In traditional web projects, in order to prevent repeated submission, the common practice is: the backend generates a unique submission token (uuid), which is stored on the server, the page initiates the request with a secondary token, and the backend verifies the request and deletes the token to ensure the uniqueness of the request.

However, the practice of appeal is that both the front and back ends need to be changed, if at the beginning of the project, it can be realized, but in the later stage of the project, many functions have been achieved, and it is impossible to change them on a large scale.

Train of thought

1. Custom annotation @ NoRepeatSubmit marks requests submitted in all Controller

two。 Intercept all methods marked @ NoRepeatSubmit through AOP

3. Before the execution of the business method, obtain the current request address of the token or JSessionId+ of the current user, as a unique key, to obtain the redis distributed lock. If acquired concurrently at this time, only one thread can obtain it.

4. Release the lock after the service is executed

About Redis distributed Lock

Redis is used for load balancing deployment. For stand-alone projects, you can use a native thread-safe Cache instead of Redis.

Code

Custom annotation

Import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target / * * @ ClassName NoRepeatSubmit * @ Description described here * @ Author admin * @ Date 16:16 on 2021-3-2 * / @ Target (ElementType.METHOD) @ Retention (RetentionPolicy.RUNTIME) public @ interface NoRepeatSubmit {/ * setting request lock time * * @ return * / int lockTime () default 10;} AOPpackage com.hongkun.aop / * * @ ClassName RepeatSubmitAspect * @ Description describe here * @ Author admin * @ Date 16:15 on 2021-3-2 * / import com.hongkun.until.ApiResult;import com.hongkun.until.Result;import com.hongkun.until.RedisLock;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory Import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.util.Assert;import org.springframework.web.context.request.RequestAttributes;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.util.UUID;import java.util.concurrent.TimeUnit / * * @ author liucheng * @ since 2020-01-15 * prevent the API from repeatedly submitting * / @ Aspect@Componentpublic class RepeatSubmitAspect {private static final Logger LOGGER = LoggerFactory.getLogger (RepeatSubmitAspect.class); @ Autowired private RedisLock redisLock; @ Pointcut ("@ annotation (noRepeatSubmit)") public void pointCut (NoRepeatSubmit noRepeatSubmit) {} @ Around ("pointCut (noRepeatSubmit)") public Object around (ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {int lockSeconds = noRepeatSubmit.lockTime () RequestAttributes ra = RequestContextHolder.getRequestAttributes (); ServletRequestAttributes sra = (ServletRequestAttributes) ra; HttpServletRequest request = sra.getRequest (); Assert.notNull (request, "request can not null"); / / token or JSessionId String token = request.getHeader ("token"); String path = request.getServletPath (); String key = getKey (token, path); String clientId = getClientId () Boolean isSuccess = redisLock.lock (key, clientId, lockSeconds,TimeUnit.SECONDS); LOGGER.info ("tryLock key = [{}], clientId = [{}]", key, clientId); if (isSuccess) {LOGGER.info ("tryLock success, key = [{}], clientId = [{}]", key, clientId); / / acquisition of lock success Object result Try {/ / execution process result = pjp.proceed ();} finally {/ / unlock redisLock.unlock (key, clientId); LOGGER.info ("releaseLock success, key = [{}], clientId = [{}]", key, clientId);} return result } else {/ / failed to acquire lock, which is considered to be a repeatedly submitted request LOGGER.info ("tryLock fail, key = [{}]", key); return ApiResult.success (200, "repeat request, please try again later, null);}} private String getKey (String token, String path) {return" 00000 "+": "+ token + path" } private String getClientId () {return UUID.randomUUID (). ToString ();}} the above is about "how to combine SpringBoot with Aop+Redis to prevent repeated submission". I believe everyone has a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to learn more about the relevant knowledge, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report