自定义注解+拦截器防止重复请求

1.自定义注解类

        自定义注解需要用到元注解,如@Target、@Retention、@Document、@Inherited.

@Target:

@Target 指定注解的作用范围,该注解有以下属性值

1.ElementType.TYPE   //作用于类、接口、枚举,但不能是注解
2.ElementType.FIELD  //作用于字段、枚举
3.ElementType.METHOD  //作用于方法、不能是构造方法
4.ElementType.PARAMETER  //作用于方法的参数
5.ElementType.CONSTRUCTOR   //作用于构造函数
6.ElementType.LOCAL_VARIABLE // 局部变量,作用于本地变量或者catch语句
7.ElementType.ANNOTATION_TYPE //作用于注解
8.ElementType.PACKAGE / /作用于包   

@Retention:

@Retention 指定注解的保留策略 三个

@Retention(RetentionPolicy.SOURCE)   //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS)   //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
@Retention(RetentionPolicy.RUNTIME)   //在运行时可以通过反射获取到,JVM会读取注解,同时保存在class文件中

@Document:说明该注解将被包含在javadoc中

@Inherited:说明子类可以继承父类中的该注解

编写一个自定义注解:

/**
 * 自定义注解
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation{

    /**
     * 拦截时间 单位为秒 默认值1秒
     */
    int time() default 1;
}

使用,在方法上添加上注解

    @ResponseBody
    @PostMapping("doLogin")
    @MyAnnotaton(time = 30)
    public SaResult doLogin(@RequestBody User user) {  
        return  userServerService.doLogin(user);
    }

2.配置拦截器

/**
 * 拦截器配置类
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Bean
    public LoginInterceptor getInterceptorBean(){
        return new LoginInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        String[] addPathPattern = {
                "/auth/doLogin"
        };
        String[] excludePathPattern={
                "/info/addXmlInfo",
                "/auth/registry",
        };
        
registry.addInterceptor(getInterceptorBean()).addPathPatterns(addPathPattern).excludePathPatterns(excludePathPattern);
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

3.使用拦截器防止重复请求功能

        首次访问请求,登录成功,会把这次的Ip地址和路径记录作为key,保存到session中,并设置过期时间,当第二次访问时,会拿着Ip地址和路径到session找,找到了就把请求拦截下来,返回信息。

/**
 * 认证登录拦截
 */
public class LoginInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(LoggerFactory.class);

    /**
     * 进入controller层之前拦截请求
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof ResourceHttpRequestHandler) {
            // 静态资源不做权限处理
            return true;
        }
        // 用户IP地址
        String addr = request.getRemoteAddr();
        // 访问的url地址
        String requestURI = request.getRequestURI();

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        //得到方法上的DuplicateCommitLimit注解
        DuplicateCommitLimit duplicateCommitLimit = 
 handlerMethod.getMethodAnnotation(DuplicateCommitLimit.class);
        if (duplicateCommitLimit != null) {
            String key = "duplicate_commit_" + requestURI + "_" + addr);
            boolean isLimited = false;
            Object object = request.getSession().getAttribute(key);
            if (null == object) {
                log.info("用户IP={},url地址={} 首次登录", addr, requestURI);
            } else {
                isLimited = true;
            }
            if (isLimited) {
                sendMsg(response);//返回被拦截提示信息
                return false;
            } else {
                HttpSession session = request.getSession();
                session.setMaxInactiveInterval(duplicateCommitLimit.time());
                session.setAttribute(msgVO.getKey(), true);
               }
        }
        return true;
    }

    /**
     * 设置请求的响应信息
     *
     * @param response
     */
    private void sendMsg(HttpServletResponse response) {
        SaResult saResult = new SaResult();
        saResult.setCode(4000);
        saResult.setMsg("请勿重复提交或者操作过于频繁!");
        ResponseUtils.renderJson(response, saResult.toString());
    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值