赞
踩
1.添加redis 依赖包
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
2.自定义注解 AccessLimit
@Inherited @Documented @Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface AccessLimit { //标识 指定sec时间段内的访问次数限制 int limit() default 5; //标识 时间段 int seconds() default 5; }
3. 添加拦截器 AccessLimitInterceptor
- public class AccessLimitInterceptor implements HandlerInterceptor {
-
- @Autowired
- private RedisTemplate<String, Integer> redisTemplate;
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- if (handler instanceof HandlerMethod) {
- HandlerMethod handlerMethod = (HandlerMethod) handler;
- Method method = handlerMethod.getMethod();
- if (!method.isAnnotationPresent(AccessLimit.class)) {
- return true;
- }
- AccessLimit accessLimit = method.getAnnotation(AccessLimit.class);
- if (accessLimit == null) {
- return true;
- }
- int limit = accessLimit.limit();
- int sec = accessLimit.seconds();
- String key = IPUtil.getIpAddr(request) + request.getRequestURI();
- Integer maxLimit = redisTemplate.opsForValue().get(key);
- if (maxLimit == null) {
- //set时一定要加过期时间
- redisTemplate.opsForValue().set(key, 1, sec, TimeUnit.SECONDS);
- } else if (maxLimit < limit) {
- redisTemplate.opsForValue().set(key, maxLimit + 1, sec, TimeUnit.SECONDS);
- } else {
- output(response, "请求太频繁!");
- return false;
- }
- }
- return true;
- }
-
- public void output(HttpServletResponse response, String msg) throws IOException {
- response.setContentType("application/json;charset=UTF-8");
- ServletOutputStream outputStream = null;
- try {
- outputStream = response.getOutputStream();
- outputStream.write(msg.getBytes("UTF-8"));
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- outputStream.flush();
- outputStream.close();
- }
- }
-
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
-
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
-
- }
- }

4.方法上加上注解 @AccessLimit(seconds = 60,limit = 3)
@Slf4j @RestController @RequestMapping("/app/user/login") @AllArgsConstructor public class AppUserLoginController { private final IUserService userService; @AccessLimit(seconds = 60,limit = 3) @PostMapping("/getVerificationCode") public RestResponse getVerificationCode(@RequestParam("mobile") String mobile) { try { if (!StringRegexUtils.verifyMobilePhone(mobile)) { return RestResponse.fail("手机号不正确"); } if (userService.getVerificationCode(mobile, 0)) { return RestResponse.success(); } } catch (Exception e) { e.printStackTrace(); log.error(e.getMessage()); return RestResponse.fail(e.getMessage()); } return RestResponse.fail(); }}
5.注入拦截器
@Configuration public class WebInterceptorAdapter implements WebMvcConfigurer { @Bean public HandlerInterceptor getInterceptor() { return new AccessLimitInterceptor(); } @Override public void configurePathMatch(PathMatchConfigurer configurer) { AntPathMatcher pathMatcher = new AntPathMatcher(); pathMatcher.setCaseSensitive(false); configurer.setPathMatcher(pathMatcher); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(getInterceptor()); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。