防重复提交:自定义注解 + 拦截器(HandlerInterceptor)

这篇具有很好参考价值的文章主要介绍了防重复提交:自定义注解 + 拦截器(HandlerInterceptor)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

防重复提交:自定义注解 + 拦截器(HandlerInterceptor)

一、思路:

1、首先自定义注解;

2、创建拦截器实现类(自定义类名称),拦截器(HandlerInterceptor);

3、创建类:配置拦截器路径(拦截URL规则);

二、代码示例:

1、首先自定义注解;

import java.lang.annotation.*;

/**
 * @ClassName Resubmit
 * @Descripition 自定义注解-防重复提交
 * @Author 
 * @Date 2023/8/31 10:38
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Resubmit {

    /**
     * 默认过期时间
     * 单位:秒
     *
     * @return
     */
    int value() default 100;

    /**
     * 频繁请求提示语
     *
     * @return
     */
    String messge() default "请求过于频繁,请稍后再试!";

}

2、创建拦截器实现类(自定义类名称),拦截器(HandlerInterceptor);

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

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

/**
 * @ClassName ResubmitInterceptorUtil
 * @Descripition 防重复提拦截器工具类
 * @Author 
 * @Date 2023/8/31 10:52
 */
@Slf4j
@Component
public class ResubmitInterceptorUtil implements HandlerInterceptor {

    // key: 固定前缀
    private static final String FIXED_SESSION = "repeatData";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        try {
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                // 请求方法
                Method method = handlerMethod.getMethod();
                // 获取自定义注解-防重复注解(@Resubmit)
                Resubmit annotation = method.getAnnotation(Resubmit.class);
                // 判断方法是否添加自定义注解(@Resubmit)
                if (annotation != null) {
                    //如果重复相同数据
                    if (repeatDataValidator(request)) {
                        // 自定义返回结果类
                        Result result = new Result();
                        result.setCode(500);
                        result.setMessage(annotation.messge());

                        // 设置字符集编码
                        response.setCharacterEncoding("UTF-8");
                        // response.getWriter().write(JSON.toJSONString("请勿频繁提交请求,稍后再试."));
                        response.getWriter().write(JSON.toJSONString(result));
                        return false;
                    } else {
                        return true;
                    }
                }
                return true;
            } else {
                return true;
            }
        } catch (IOException e) {
            log.error("防重复提拦截器工具类异常", e);
            return false;
        }
    }


    /**
     * 验证同一个url数据是否相同提交,相同返回true
     *
     * @param request
     * @return
     */
    private boolean repeatDataValidator(HttpServletRequest request) {

        // 获取POST请求体-body-入参
        String params = getRequestBodyParam(request);
        // 获取请求路径
        String url = request.getRequestURI();

        Map<String, String> map = new HashMap<>();
        // 组装Map key: url、 value:url+请求方法体+时间
        map.put(url, params);
        String nowUrlParams = JSON.toJSONString(map);

        Object preUrlParams = request.getSession().getAttribute(FIXED_SESSION);
        //如果上一个数据为null,表示还没有访问页面
        if (preUrlParams == null) {
            //如果上一个数据为null,表示还没有访问页面
            request.getSession().setAttribute(FIXED_SESSION, nowUrlParams);
            return false;
        } else {
            //如果上次url+数据和本次url+数据相同,则表示重复添加数据
            if (preUrlParams.equals(nowUrlParams)) {
                log.info("[请求频繁提交 repeatDataValidator URL :{}; param :{}]", url, params);
                return true;
            } else {
                //如果上次 url+数据 和本次url加数据不同,则不是重复提交
                request.getSession().setAttribute(FIXED_SESSION, nowUrlParams);
                return false;
            }

        }
    }


    /**
     * 获取请求体-body-入参
     *
     * @param request
     * @return
     */
    private String getRequestBodyParam(HttpServletRequest request) {
        BufferedReader bufferedReader = null;
        StringBuffer stringBuffer = new StringBuffer();
        try {
            bufferedReader = request.getReader();
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                stringBuffer.append(str);
            }
            bufferedReader.close();
        } catch (IOException e) {
            log.error("解析入参异常!!!", e);
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    log.error("解析入参异常!!!", e);
                }
            }
        }
        return stringBuffer.toString();
    }
}

3、创建类:配置拦截器路径(拦截URL规则);文章来源地址https://www.toymoban.com/news/detail-690133.html

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @ClassName WebMvcConfig
 * @Descripition 配置拦截路径
 * @Author 
 * @Date 2023/9/1 10:08
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private ResubmitInterceptorUtil resubmitInterceptorUtil;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 配置拦截类
        registry.addInterceptor(resubmitInterceptorUtil)
                // 设置拦截路径URL
                .addPathPatterns("/**");
    }

}

到了这里,关于防重复提交:自定义注解 + 拦截器(HandlerInterceptor)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Boot整合日期转换器(Converter)和拦截器(HandlerInterceptor)

    配置日期转换器(WebMvcConfigurer) 说明         WebMvcConfigurer配置类其实是 Spring 内部的一种配置方式,采用 JavaBean 的形式来代替传统的 xml 配置文件形式针对框架进行个性化定制,例如:拦截器,类型转化器等等。 代码示例 配置拦截器(WebMvcConfigurer)

    2024年01月17日
    浏览(64)
  • Spring Boot 3自定义注解+拦截器+Redis实现高并发接口限流

    在当今互联网应用开发中,高并发访问是一个常见的挑战。为了保障系统的稳定性和可靠性,我们需要对接口进行限流,防止因过多的请求导致系统崩溃。 本文将介绍如何利用Spring Boot 3中的自定义注解、拦截器和Redis实现高并发接口限流,帮助程序员解决这一挑战。 1. 自定

    2024年04月28日
    浏览(46)
  • Spring Boot学习随笔- 拦截器实现和配置(HandlerInterceptor、addInterceptors)、jar包部署和war包部署

    学习视频:【编程不良人】2021年SpringBoot最新最全教程 拦截器 :Interceptor 拦截 中断 类似于javaweb中的Filter,不过没有Filter那么强大 作用 Spring MVC的拦截器是一种用于在请求处理过程中进行预处理和后处理的机制。拦截器可以在请求到达控制器之前和之后执行一些操作,例如日

    2024年02月02日
    浏览(45)
  • Spring Boot入门(23):记录接口日志再也不难!用AOP和自定义注解给Spring Boot加上日志拦截器!

            在上两期中,我们着重介绍了如何集成使用 Logback 与 log4j2 日志框架的使用,今天我们讲解的主题依旧跟日志有关,不过不是使用何种开源框架,而是自己动手造。         Spring的核心之一AOP;AOP翻译过来叫面向切面编程, 核心就是这个切面. 切面表示从业务逻辑中

    2024年02月11日
    浏览(52)
  • 【Spring底层原理高级进阶】轻松掌握 Spring MVC 的拦截器机制:深入理解 HandlerInterceptor 接口和其实现类的用法

     🎉🎉欢迎光临🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟特别推荐给大家我的最新专栏 《Spring 狂野之旅:底层原理高级进阶》 🚀 本专栏纯属为爱发电永久免费!!! 这是苏泽的个人主页可以看到我其他的内容哦👇👇 努力的苏泽 http://suze

    2024年02月20日
    浏览(52)
  • Mybatis拦截器注解@Intercepts与@Signature注解属性说明

    可能有些新手使用mybatis拦截器的时候可能没太懂@Signature注解中type,method,args的用法 首先mybatis拦截器可以拦截如下4中类型 Executor sql的内部执行器 ParameterHandler 拦截参数的处理 StatementHandler 拦截sql的构建 ResultSetHandler 拦截结果的处理 type:就是指定拦截器类型(ParameterHandl

    2024年02月05日
    浏览(43)
  • 【SpringMVC】JSR 303与拦截器注解使用

       JSR 303,它是Java EE(现在称为Jakarta EE)规范中的一部分。JSR 303定义了一种用于验证Java对象的标准规范,也称为Bean验证。         Bean验证是一种用于验证对象属性的框架,它可以确保对象符合特定的规则和约束。这些规则可以包括字段的非空性、长度限制、格式验证等。

    2024年02月07日
    浏览(49)
  • quarkus依赖注入之十一:拦截器高级特性上篇(属性设置和重复使用)

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇是《quarkus依赖注入》系列的第十一篇,之前的[《拦截器》]学习了拦截器的基础知识,现在咱们要更加深入的了解拦截器,掌握两种高级用法:拦截器属性和重复使用拦截器 先来回顾拦截器的基

    2024年02月13日
    浏览(33)
  • 自定义拦截器实现

    在 Spring MVC 框架中, 拦截器作为一种机制, 用于对请求进行拦截. 拦截器可以在请求进入处理器之前、处理器返回处理之后、视图渲染之前等各个环节进行拦截. 拦截器通常用于实现一下功能 : 鉴权和身份认证 日志记录和统计 请求参数和校验和过滤 缓存和性能优化 路径重定向

    2024年02月09日
    浏览(52)
  • SpringBoot Redis 注解 拦截器来实现接口幂等性校验

    幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次 比如:订单接口, 不能多次创建订单 支付接口, 重复支付同一笔订单只能扣一次钱 支付宝回调接口, 可能会多次回调, 必须处理重复回调 普通表单提交接口, 因为网络超时等原因多次点击提

    2024年01月19日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包