Java实现防重复提交,使用自定义注解的方式

目录

1.背景

2.思路

3.实现

创建自定义注解

编写拦截器

4.使用

5.验证

6.总结


1.背景

在进行添加操作时,防止恶意点击,后端进行请求接口的防重复提交

2.思路

通过拦截器搭配自定义注解的方式进行实现,拦截器拦截请求,使用注解的方式可以提高复用性和灵活性。

3.实现

创建自定义注解

package com.zsp.quartz.Interceptor;
import java.lang.annotation.*;

/**
 * 自定义注解防止表单重复提交
 */
@Inherited  //可以被继承
@Target(ElementType.METHOD) // 使用范围
@Retention(RetentionPolicy.RUNTIME) 
// RetentionPolicy.RUNTIME表示注解在编译时和运行时都保留
// 可以通过反射机制在运行时访问和处理注解
@Documented
public @interface RepeatSubmit {

}

重要:@Retention,因为要在拦截器那里通过反射机制对添加了该注解的方法进行处理。

编写拦截器

package com.zsp.quartz.Interceptor;

//怎么拦截

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zsp.quartz.util.jwtUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class MyInterceptor implements HandlerInterceptor {
    private final Map lastRequestMap = new HashMap<>();
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Map map=new HashMap<>();
        // 防重复提交
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                Method method = handlerMethod.getMethod();
                // method.getAnnotation:获取指定方法上的指定注解 annotationClass.它返回一个注解对象,如果该方法上不存在指定的注解,则返回 null。
                RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
                if (annotation != null) {
                    String key = request.getRequestURI();
                    String lastRequestKey = lastRequestMap.get(handlerMethod.getMethod().getName());
                    if (lastRequestKey != null && lastRequestKey.equals(key)) {
                        map.put("state",false);//设置状态
                        map.put("code",201);
                        map.put("msg","请勿重复提交表单!");
                        String json = new ObjectMapper().writeValueAsString(map);
                        response.setContentType("application/json;charset=UTF-8");
                        response.getWriter().println(json);
                        return false;
                    }
                    lastRequestMap.put(handlerMethod.getMethod().getName(), key);
                }
                return true;//放行请求
            }
        return false;
    }
}

4.使用

直接在方法上加自定义注解

    @RepeatSubmit
    @PostMapping("/test")
    public String login() {
        return "你好啊,doPost方法";
    }

5.验证

第一次点击

Java实现防重复提交,使用自定义注解的方式_第1张图片

第二次点击
Java实现防重复提交,使用自定义注解的方式_第2张图片

6.总结

在这里只做实现思路,用了Map 来判断。
在实际开发中通过存入redis,并设置过期时间来判断是否重复提交。
以下是简单举例。


        String nowParams = "前端传的value";
        String url = request.getRequestURI();
        String cacheKey = String.format("自己的key,可以是随机数", url);
        String preParams = redisTemplate.opsForValue().get(cacheKey).toString();
        if (preParams == null || "".equals(preParams)){
            //用户提交参数缓存10秒
            redisTemplate.opsForValue().set(cacheKey, nowParams, 10, TimeUnit.SECONDS);
            return false;
        }
        if (compareParams(nowParams, preParams)) {
            return true;
        }
        //用户提交参数缓存10秒
        redisTemplate.opsForValue().set(cacheKey, nowParams, 10, TimeUnit.SECONDS);
        return false;



    /**
     * 判断参数是否相同
     */
    private boolean compareParams(String nowParams, String preParams) {
        return nowParams.equals(preParams);
    }

你可能感兴趣的:(java,开发语言)