新增注解类

NotRepeatSubmit.java
package com.example.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 自定义注解,防止重复提交。
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotRepeatSubmit { /** 过期时间,单位毫秒 **/
long value() default 5000;
}

ApiUti.java

package com.example.demo.annotation;

import com.example.demo.token.NotRepeatSubmit;
import org.springframework.messaging.handler.HandlerMethod; import java.lang.reflect.Method; /**
* API工具类
*/
public class ApiUtil { /**
* 获取方法上的@NotRepeatSubmit注解
*
* @param handler
* @return
*/
public static NotRepeatSubmit getNotRepeatSubmit(Object handler) {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
NotRepeatSubmit annotation = method.getAnnotation(NotRepeatSubmit.class);
return annotation;
}
return null;
}
}

拦截器类

MyInterceptor.java

package com.example.demo.annotation;

import com.example.demo.token.NotRepeatSubmit;
import io.jsonwebtoken.lang.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit; /**
* 拦截器
*/
@Component
public class MyInterceptor extends HandlerInterceptorAdapter { @Autowired
private RedisTemplate redisTemplate; /**
* @param request
* @param response
* @param handler 访问的目标方法
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //这是请求接口时带的随机字符串
String sign = request.getHeader("sign"); // 获取注解上的超时时间 默认为5分钟
NotRepeatSubmit notRepeatSubmit = ApiUtil.getNotRepeatSubmit(handler);
long expireTime = notRepeatSubmit == null ? 5 * 60 * 1000 : notRepeatSubmit.value(); // 拒绝重复调用(第一次访问时存储,过期时间和请求超时时间保持一致), 只有标注不允许重复提交注解的才会校验
if (notRepeatSubmit != null) {
boolean exists = redisTemplate.hasKey(sign);
Assert.isTrue(!exists, "请勿重复提交");
redisTemplate.opsForValue().set(sign, 0, expireTime, TimeUnit.MILLISECONDS);
} return super.preHandle(request, response, handler);
}
}
WebMvcConfiguration.java
package com.example.demo.annotation;

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.WebMvcConfigurationSupport; /**
* 将自己写的MyInterceptor添加到拦截配置器中 尽量使用实现 WebMvcConfigurer 的接口的方式
*/
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport { @Autowired
private MyInterceptor myInterceptor; @Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
registry.addInterceptor(myInterceptor)
.addPathPatterns("/api/**");
}
}

使用方式 控制器类

package com.example.demo.annotation;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController; /**
* 请求控制器
*/
@Slf4j
@RestController
public class TestController { /**
* @NotRepeatSubmit 是自定义注解 防止重复提交
* @return
*/
@NotRepeatSubmit(5000)
@PostMapping("/api/test")
public void test(String name) { } }

SpringBoot 自定义注解的更多相关文章

  1. [技术博客] SPRINGBOOT自定义注解

    SPRINGBOOT自定义注解 在springboot中,有各种各样的注解,这些注解能够简化我们的配置,提高开发效率.一般来说,springboot提供的注解已经佷丰富了,但如果我们想针对某个特定情景 ...

  2. SpringBoot 自定义注解 实现多数据源

    SpringBoot自定义注解实现多数据源 前置学习 需要了解 注解.Aop.SpringBoot整合Mybatis的使用. 数据准备 基础项目代码:https://gitee.com/J_look/ ...

  3. java/springboot自定义注解实现AOP

    java注解 即是注释了,百度解释:也叫元数据.一种代码级别的说明. 个人理解:就是内容可以被代码理解的注释,一般是一个类. 元数据 也叫元注解,是放在被定义的一个注解类的前面 ,是对注解一种限制. ...

  4. 使用IDEA创建SpringBoot自定义注解

    创建SpringBoot项目 添加组织名 选择web 输入项目名称 创建后目录结构为 使用Spring的AOP先加入Maven依赖 <dependency> <groupId> ...

  5. springboot+自定义注解实现灵活的切面配置

    利用aop我们可以实现业务代码与系统级服务例如日志记录.事务及安全相关业务的解耦,使我们的业务代码更加干净整洁. 最近在做数据权限方面的东西,考虑使用切面对用户访问进行拦截,进而确认用户是否对当前数据 ...

  6. SpringBoot自定义注解、AOP打印日志

    前言 在SpringBoot中使用自定义注解.aop切面打印web请求日志.主要是想把controller的每个request请求日志收集起来,调用接口.执行时间.返回值这几个重要的信息存储到数据库里 ...

  7. SpringBoot自定义注解

    1.注解的概念 注解是一种能被添加到java代码中的元数据,类.方法.变量.参数和包都可以用注解来修饰.注解对于它所修饰的代码并没有直接的影响. 2.注解的使用范围 1)为编译器提供信息:注解能被编译 ...

  8. SpringBoot自定义注解+异步+观察者模式实现业务日志保存

    一.前言 我们在企业级的开发中,必不可少的是对日志的记录,实现有很多种方式,常见的就是基于AOP+注解进行保存,但是考虑到程序的流畅和效率,我们可以使用异步进行保存,小编最近在spring和sprin ...

  9. SpringBoot自定义注解@YamlPropertySource加载yml或者yaml文件(扩展了@PropertySource)

    1:概述 SpringBoot的@PropertySource注解只支持加载 properties结尾的文件.当使用@ConfigurationProperties 注解配合@EnableConfig ...

随机推荐

  1. R语言与医学统计图形-【30】流行病学数据可视化

    sjPlot包适用于社会科学.流行病学中调查数据可视化,且能和SPSS数据无缝对接(流行病学问卷调查录入Epidata软件后,都会转成SPSS格式或EXCEL格式保存). 辅助包sjmisc进行数据转 ...

  2. 关于GCC编译

    GCC参数详解 gcc是gnu compiler collection 的简称,他包含了多种语言的编译器,如C, C++, Objective-C, Objective-C++, Java, Fort ...

  3. python19 操作mysql

    connect 模块下载 https://dev.mysql.com/downloads/connector/python/ import mysql.connector con = mysql.co ...

  4. iptables_超解

    查询: -t选项,指定要操作的表,使用-L选项,查看-t选项对应的表的规则,-L选项的意思是,列出规则,所以,上述命令的含义为列出filter表的所有规则 显示出了3条链INPUT链.FORWARD链 ...

  5. JAVA中复制数组的方法

    在JAVA里面,可以用复制语句"A=B"给基本类型的数据传递值,但是如果A,B是两个同类型的数组,复制就相当于将一个数组变量的引用传递给另一个数组;如果一个数组发生改变,那么 引用 ...

  6. 学习Java的第十八天

    一.今日收获 1.java完全学习手册第三章算法的3.1比较值 2.看哔哩哔哩上的教学视频 二.今日问题 1.在第一个最大值程序运行时经常报错. 2.哔哩哔哩教学视频的一些术语不太理解,还需要了解 三 ...

  7. flink-----实时项目---day04-------1. 案例:统计点击、参与某个活动的人数和次数 2. 活动指标多维度统计(自定义redisSink)

    1. 案例 用户ID,活动ID,时间,事件类型,省份 u001,A1,2019-09-02 10:10:11,1,北京市 u001,A1,2019-09-02 14:10:11,1,北京市 u001, ...

  8. Flume对接Kafka

    目录 一.简单实现 1)flume的配置文件 二.自定义interceptor(使用kafka sink) 1)自定义 flume 拦截器 2)编写 flume 的配置文件 3)创建topic 4)启 ...

  9. flink02------1.自定义source 2. StreamingSink 3 Time 4窗口 5 watermark

    1.自定义sink 在flink中,sink负责最终数据的输出.使用DataStream实例中的addSink方法,传入自定义的sink类 定义一个printSink(),使得其打印显示的是真正的ta ...

  10. Set、Map、WeakSet 和 WeakMap 的区别

    先总结: Set1.  成员不能重复2. 只有健值,没有健名,有点类似数组.3. 可以遍历,方法有add, delete,hasweakSet 1. 成员都是对象 2. 成员都是弱引用,随时可以消失. ...