当前位置:网站首页>Several methods to prevent repeated form submission + actual measurement
Several methods to prevent repeated form submission + actual measurement
2022-06-22 08:22:00 【Hanxiaozhi】
1. Front-end processing ( scene : Used when the user clicks many times in case of network delay submit Button causes the form to be submitted repeatedly )
①: After the form submission is controlled by an identifier , Submitting again will directly return to processing .
Var isCommitted = false; // Identification of whether the form should be submitted , The default is false
function dosubmit() {
//start hzj
If(isCommitted == false){
// After submitting the form , Set whether the form has been submitted to true
isCommitted = true;
// return true Let the form submit normally
return true;
}else{
return false; // return false Form not submitted
}
//end hzj
}
** summary :** Add the above judgment logic before submitting the business and after the business processing
②: After clicking the submit button once , Set this button to unavailable processing .
function dosubmit() {
// Get the form submit button
Var btnSubmit = documen.getElementById(“sumit”);
// Set the form submit button to unavailable , It can prevent users from clicking the submit button again to submit
btnSubmit.disabled = “disabled”;
// return true Make the form available for submission
return true;
}
** summary :** Put this method after the first submit button succeeds , The button will be set to the non clickable state .
2. The back-end processing ( scene 1: After the form is submitted , The user clicks - Refresh - Button causes the form to be submitted repeatedly . scene 2: After the user form is submitted , Click on the browser's - back off - Button , Go back to the form submission page , The resubmit button causes the form to be resubmitted .)
①: Add a single key constraint to the database ( Simple and crude )
When creating tables in the database ID Field add primary key constraint , user name 、 mailbox 、 Telephone and other fields plus uniqueness constraints . Make sure that only one piece of data can be added to the database .
Database plus uniqueness constraint sql:
alter table tableName_xxx add unique key uniq_xxx(field1, field2)
The server catches the inserted data exception in time :
try {
xxxMapper.insert(user);
} catch (DuplicateKeyException e) {
logger.error("user already exist");
}
** summary :** For adding stock in to fields in the table
②:session Technical realization
a. Generate a unique random identification number on the server side , The technical term is called Token( token ), At the same time in the current user's Session Save this in the domain Token.
b. And then Token Sent to client Form In the form , stay Form The form uses hidden fields to store this Token, The form is submitted with this Token Submit to the server together .
c. Then, the server side judges the information submitted by the client Token And server-side generated Token Is it consistent , If it's not consistent , That's repeated submission , At this point, the server can not handle the form submitted repeatedly . If the same, process the form submission , Clear the current user's after processing Session The ID number stored in the domain .
//1. Sign in controller layer
String token = TokenProccessor.getInstance().makeToken();// Create token
request.getSession().setAttribute("token", token); // Use on the server session preservation token( token )
return data;// Return success data , Jump to the home page of the seat side ( take token Put in data in , The return page will token Put it in the form label in the hidden field )
//2. Put... In the front page form token
<input type="hidden" name="token" value="token value "/>
//3. The logical layer that actually handles the submission business
boolean b = isRepeatSubmit(request);// Determine whether the user is submitting repeatedly
if(b==true){
System.out.println(" Please do not repeat the submission ");
return;
}
request.getSession().removeAttribute("token");// remove session Medium token
System.out.println(" Handle user submitted requests !!");
}
/** * Judge whether the token submitted by the client is consistent with the token generated by the server * @param request * @return * true The user repeatedly submitted the form * false The user did not submit the form repeatedly */
private boolean isRepeatSubmit(HttpServletRequest request) {
String client_token = request.getParameter("token");
//1、 If there is no... In the form data submitted by the user token, Then the user repeatedly submitted the form
if(client_token==null){
return true;
}
// Take out and store in Session Medium token
String server_token = (String) request.getSession().getAttribute("token");
//2、 If the current user's Session Does not exist in the Token( token ), Then the user repeatedly submitted the form
if(server_token==null){
return true;
}
//3、 Stored in Session Medium Token( token ) With the form submitted Token( token ) Different , Then the user repeatedly submitted the form
if(!client_token.equals(server_token)){
return true;
}
return false;
}
//4. Generate token Tool class of
public class TokenProccessor {
/* * Singleton design pattern ( Ensure that there is only one object of the class in memory ) *1、 Private the constructor of the class *2、 Create a class object by yourself *3、 Provide a public approach to the outside world , Returns the object of the class */
private TokenProccessor(){
}
private static final TokenProccessor instance = new TokenProccessor();
/** * Returns the object of the class * @return */
public static TokenProccessor getInstance(){
return instance;
}
/** * Generate Token * Token:Nv6RRuGEVvmGjB+jimI/gw== * @return */
public String makeToken(){
//checkException
// 7346734837483 834u938493493849384 43434384
String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
// Data fingerprint 128 Bit length 16 Bytes md5
try {
MessageDigest md = MessageDigest.getInstance("md5");
byte md5[] = md.digest(token.getBytes());
//base64 code -- Any binary coded plaintext character adfsdfsdfsf
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(md5);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
** summary :** Use session technology , One user corresponds to one session Containers
③: Use AOP Custom cut in implementation
1. Custom prevent duplicate submission flag (@AvoidRepeatableCommit).
2. For those that need to prevent repeated submission Congtroller Inside mapping Method with this annotation .
3. newly added Aspect The breakthrough point , by @AvoidRepeatableCommit Join the entry point .
4. Every time a form is submitted ,Aspect Will save the current key To reids( The expiration time must be set ).
5. When submitting repeatedly Aspect Will judge the present redis Is there any right to key, Intercept if any .
// First, customize the annotations
/** * Avoid duplicate submissions * @author * @version * @since */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AvoidRepeatableCommit {
/** * Cannot submit repeatedly within the specified time , Unit millisecond , Default 10000 millisecond */
long timeout() default 10000 ;
}
// Create the section class
/** * Repeated submission aop */
@Aspect//
@Component
public class AvoidRepeatableCommitAspect {
private static final Logger logger = Logger.getLogger(AvoidRepeatableCommitAspect.class);
@SuppressWarnings("rawtypes")
@Autowired
private RedisTemplate redisTemplate;
/** * @param point Connection point */
@SuppressWarnings("unchecked")
@Around("@annotation(com.***.annotation.AvoidRepeatableCommit)")// Cut in the face
public Object around(ProceedingJoinPoint point) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String ip = IPUtil.getIP(request);
// here method Get the proxy object ( Generated by proxy pattern ) Methods
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
// here realMethod It's the target ( The original ) Methods
// Method realMethod = point.getTarget().getClass().getDeclaredMethod(signature.getName(),method.getParameterTypes());
// Target class 、 Method
String className = method.getDeclaringClass().getName();
String name = method.getName();
String ipKey = String.format("%s#%s",className,name);
int hashCode = Math.abs(ipKey.hashCode());
String key = String.format("%s_%d",ip,hashCode);
//logger.info("ipKey={},hashCode={},key={}",ipKey,hashCode,key);
logger.info(String.format("ipKey={},hashCode={},key={}",ipKey,hashCode,key));
// Get annotation objects through reflection technology
AvoidRepeatableCommit avoidRepeatableCommit = method.getAnnotation(AvoidRepeatableCommit.class);
long timeout = avoidRepeatableCommit.timeout();
if (timeout < 0){
// Expiration time 10 second
timeout = 10000;
}
// obtain key The value of the key
String value = (String) redisTemplate.opsForValue().get(key);
if (StringUtils.isNotBlank(value)){
return new Message(1," Do not submit again !");
}
// Add a value of string type ,key It's a key ,value Is the value .
redisTemplate.opsForValue().set(key, UUIDUtil.uuid(),timeout,TimeUnit.MILLISECONDS);
// Return to continue executing the intercepted method
return point.proceed();
}
}
Be careful :
This class has two annotations , Namely @Component and @Aspect,
@Component Is making AvoidRepeatableCommitAspect suffer Spring Hosting and instantiating .
@Aspect Is to make this class have AOP function ( You can think of it this way ) Both notes are indispensable
There is only one method in the class , The name is called around, In fact, it is to prevent repeated submission !
// Add... To the method I need to prevent duplicate submission Custom annotation
// newly added
@AvoidRepeatableCommit // Custom annotation
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody Message create(SourceEntity sourceEntity) {
// Set creation time
sourceEntity.setGmt_create(new Date());
// Save database
sourceEntity.save(sourceEntity);
return MessageUtil.message("sourceEntity.create.success");
}
** summary :** It's done here , The main step is to submit the form every time ,Aspect Will save the current key To reids( Set the expiration time first ). When submitting repeatedly Aspect Will judge the present redis Is there any right to key, Intercept if any . Let go if you don't .
边栏推荐
- Installing SQL Server 2008 by image in Windows Service 2008
- Type of sub database and sub table
- Master data management system
- Summary of sub database and sub table 1
- Oracle database pl/sql procedure body, cursor, stored procedure
- Summary of basic knowledge of Oracle database SQL statement II: data operation language (DML)
- Mt4/mql4 getting started to mastering EA tutorial lesson 8 - common functions of MQL language (VIII) - common time function
- 培养以科学技能为本的Steam教育
- Easyui数据表实现增删改
- Design skills of common table structure in database design
猜你喜欢

Mt4/mql4 getting started to proficient in foreign exchange EA automatic trading tutorial - identify the emergence of the new K line

Implementation and landing of any to any real-time voice change RTC dev Meetup

Fastcorrect: speech recognition fast error correction model RTC dev Meetup

Concatenate the specified character at the end of a number in a string

Five skills to be an outstanding cloud architect

Example of QT qtableview

安装 MySQL 服务时提示 InstallRemove of the Service Denied

Type of sub database and sub table

Postgresql源码(56)可扩展类型分析ExpandedObject/ExpandedRecord

Email giant exposes serious vulnerability, user data is stolen
随机推荐
Email giant exposes serious vulnerability, user data is stolen
MySQL queries data within one hour
How to design the dead shot, the best and eye-catching performance of the watch Vanguard
Example of QT qtableview
Submit values of various inputs of the form
[Oracle database] mammy tutorial Day12 character function
The solution to the problem of the first screen picture loading flicker
I spring and autumn web Penetration Test Engineer (elementary) learning notes (Chapter 1)
[Oracle database] mammy tutorial Day11 numerical function
Design skills of common table structure in database design
Using KDJ metrics on MT4
Prompt installremove of the Service denied when installing MySQL service
Interpreting the technology group in maker Education
SQL triggers
Calculation days ()
Oracle execution plan analysis
0 basic self-study STM32 (wildfire) -- what is a register?
QT control adds double click event
Chapter VIII web project testing (the end of this chapter)
每周推荐短视频:什么是“计算世界”?