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

news2025/1/17 14:04:54

目录

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<String, String> lastRequestMap = new HashMap<>();
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Map<String,Object> 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.验证

第一次点击

第二次点击

6.总结

在这里只做实现思路,用了Map<key,value> 来判断。
在实际开发中通过存入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);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1081115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在 Keras 中开发具有注意力的编码器-解码器模型

link 【翻译自 &#xff1a; How to Develop an Encoder-Decoder Model with Attention in Keras 】 【说明&#xff1a;Jason Brownlee PhD大神的文章个人很喜欢&#xff0c;所以闲暇时间里会做一点翻译和学习实践的工作&#xff0c;这里是相应工作的实践记录&#xff0c;…

大数据Doris(八):启动FE步骤

文章目录 启动FE步骤 一、配置环境变量 二、​​​​​​​创建doris-mate

变分自动编码器 (VAE)02/2 PyTorch 教程

一、说明 在自动编码器中&#xff0c;来自输入数据的信息被映射到固定的潜在表示中。当我们旨在训练模型以生成确定性预测时&#xff0c;这特别有用。相比之下&#xff0c;变分自动编码器&#xff08;VAE&#xff09;将输入数据转换为变分表示向量&#xff08;顾名思义&#xf…

气象台卫星监测vr交互教学增强学生的学习兴趣和动力

对地观测是以地球为研究对象&#xff0c;依托卫星、飞船等光电仪器&#xff0c;进行各种探测活动&#xff0c;其核心是遥感技术&#xff0c;因此为了让遥感专业学员能提前熟悉对地观测规则、流程、方法及注意事项&#xff0c;借助VR虚拟现实制作的三维仿真场景&#xff0c;能让…

全新彩虹商城时光模板知识付费系统源码+内有5000多商品+易支付源码

源码简介&#xff1a; 全新彩虹商城时光模板知识付费系统源码&#xff0c;这是最新的彩虹知识付费商城系统&#xff0c;具备众多强大且实用的功能。首先&#xff0c;它支持二级分类和多级分销&#xff0c;使得商品分类更为清晰&#xff0c;销售网络更具扩展性。 其次&#xf…

机器人轨迹规划算法的研究现状

近年来&#xff0c;随着机器人技术的迅速发展&#xff0c;机器人在工业、医疗、军事等领域的应用越来越广泛。机器人轨迹规划是机器人控制的重要环节之一&#xff0c;它决定了机器人在执行任务时的运动轨迹&#xff0c;直接影响机器人的精度、速度和稳定性。因此&#xff0c;机…

【PCIE720】基于PCIe总线架构的高性能计算(HPC)硬件加速卡

PCIE720是一款基于PCI Express总线架构的高性能计算&#xff08;HPC&#xff09;硬件加速卡&#xff0c;板卡采用Xilinx的高性能28nm 7系列FPGA作为运算节点&#xff0c;在资源、接口以及时钟的优化&#xff0c;为高性能计算提供卓越的硬件加速性能。板卡一共具有5个FPGA处理节…

代码混淆界面介绍

代码混淆界面介绍 代码混淆功能包括oc&#xff0c;swift&#xff0c;类和函数设置区域。其他flutter&#xff0c;混合开发的最终都会转未oc活着swift的的二进制&#xff0c;所以没有其他语言的设置。 代码混淆功能分顶部的显示控制区域&#xff1a;显示方式&#xff0c;风险等…

python 深度学习 解决遇到的报错问题6

目录 一、解决报错HTTPSConnectionPool(hosthuggingface.co, port443): Max retries exceeded with url: /bert-base-uncased/resolve/main/vocab.txt (Caused by ConnectTimeoutError(, Connection to huggingface.co 如何从huggingface官网下载模型 二、nx.draw if cf._ax…

jupyter 切换虚拟环境

当前只有两个环kernel 我已经创建了很多虚拟环境&#xff0c;如何在notebook中使用这些虚拟环境呢&#xff1f;请看下面 比如说我要添加nlp 这个虚拟环境到notebook中 1. 切换到nlp环境 2. 安装如下模块 pip install ipykernel 3. 执行如下命令 python -m ipykernel install …

VS2019如何显示和去除控制台页面

这是控制台页面&#xff1a; 方法&#xff1a; 选中目标项目&#xff0c;右键--->属性--->配置属性--->链接器--->系统--->子系统--->(窗口/控制台)

地级市HVV | 未授权访问合集

在网站前后端分离盛行下&#xff0c;将大部分权限控制交给前端&#xff0c;导致js中隐藏未授权或者可绕过的前端鉴权。前后端分离的好处是提高开发效率&#xff0c;同时防止黑客更直接的对服务器造成危害&#xff0c;但权限控制的工作量全部交给前端会导致大量页面未授权或者后…

面试经典 150 题 1 —(双指针)— 125. 验证回文串

125. 验证回文串 方法一 class Solution { public:bool isPalindrome(string s) {string newStr "";for(int fast 0; fast < s.size(); fast){if(isalnum(s[fast]))){newStr tolower(s[fast]);}}string tmp newStr;reverse(tmp.begin(), tmp.end());if(strcm…

【计算机网络】TCP协议与UDP协议详解

文章目录 一、传输层 1、1 再次理解传输层 1、2 再次理解端口号 1、2、1 端口号范围划分 1、2、2 认识知名端口号 1、3 网络常用指令netstat 与 pidof 二、UDP协议 2、1 UDP协议的报文 2、2 UDP的特点 2、3 UDP的缓冲区 三、TCP协议 3、1 TCP协议的报文 3、2 确认应答 3、3 按…

计算机毕业设计选什么题目好?springboot 个人健康信息管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

基于SpringBoot的抗疫物资管理系统

目录 前言 一、技术栈 二、系统功能介绍 用户管理 公告信息管理 轮播图管理 物质分类管理 物质信息管理 物质入库管理 物质出库管理 个人信息 前台首页功能实现 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着现在网络的快速发展&#xff0c;网…

简单制作RT-Thread Studio的CH32V303的BSP支持包

简单制作RT-Thread Studio的CH32V303的BSP支持包 开原仓库链接在此&#xff1a;RTT_Studio_BSP_CH32V303 参考 CH32V307V-R1&#xff08;V1.0.8&#xff09;的 BSP&#xff0c;更新了外设驱动库之类的。 可以在 RT-Thread SDK 管理器中导入离线资源包&#xff0c;可以新建 RT…

CSS学习基础知识

CSS学习笔记 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width,…

Linux Centos7 下使用yum安装的nginx平滑升级

1. 查看当前nginx版本 1nginx -v2. 查看centos版本 1cat /etc/redhat-release3. 创建一个新的文件nginx.repo&#xff0c;其中第三行的7是因为我的centos版本是7点多的&#xff0c;你看自己是多少就改多少 1vim /etc/yum.repos.d/nginx.repo23[nginx]4namenginx repo 5baseu…

基于 ACK Fluid 的混合云优化数据访问(三):加速第三方存储的读访问,降本增效并行

作者&#xff1a;车漾 前文回顾&#xff1a; 本系列将介绍如何基于 ACK Fluid 支持和优化混合云的数据访问场景&#xff0c;相关文章请参考&#xff1a; 基于 ACK Fluid 的混合云优化数据访问&#xff08;一&#xff09;&#xff1a;场景与架构 基于 ACK Fluid 的混合云优化…