煙臺(tái)網(wǎng)站制作專業(yè)今日熱點(diǎn)
防重復(fù)提交:自定義注解 + 攔截器(HandlerInterceptor)
一、思路:
1、首先自定義注解;
2、創(chuàng)建攔截器實(shí)現(xiàn)類(自定義類名稱),攔截器(HandlerInterceptor);
3、創(chuàng)建類:配置攔截器路徑(攔截URL規(guī)則);
二、代碼示例:
1、首先自定義注解;
import java.lang.annotation.*;/*** @ClassName Resubmit* @Descripition 自定義注解-防重復(fù)提交* @Author * @Date 2023/8/31 10:38*/ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface Resubmit {/*** 默認(rèn)過(guò)期時(shí)間* 單位:秒** @return*/int value() default 100;/*** 頻繁請(qǐng)求提示語(yǔ)** @return*/String messge() default "請(qǐng)求過(guò)于頻繁,請(qǐng)稍后再試!";}
2、創(chuàng)建攔截器實(shí)現(xiàn)類(自定義類名稱),攔截器(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 防重復(fù)提攔截器工具類* @Author * @Date 2023/8/31 10:52*/ @Slf4j @Component public class ResubmitInterceptorUtil implements HandlerInterceptor {// key: 固定前綴private static final String FIXED_SESSION = "repeatData";@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {try {if (handler instanceof HandlerMethod) {HandlerMethod handlerMethod = (HandlerMethod) handler;// 請(qǐng)求方法Method method = handlerMethod.getMethod();// 獲取自定義注解-防重復(fù)注解(@Resubmit)Resubmit annotation = method.getAnnotation(Resubmit.class);// 判斷方法是否添加自定義注解(@Resubmit)if (annotation != null) {//如果重復(fù)相同數(shù)據(jù)if (repeatDataValidator(request)) {// 自定義返回結(jié)果類Result result = new Result();result.setCode(500);result.setMessage(annotation.messge());// 設(shè)置字符集編碼response.setCharacterEncoding("UTF-8");// response.getWriter().write(JSON.toJSONString("請(qǐng)勿頻繁提交請(qǐng)求,稍后再試."));response.getWriter().write(JSON.toJSONString(result));return false;} else {return true;}}return true;} else {return true;}} catch (IOException e) {log.error("防重復(fù)提攔截器工具類異常", e);return false;}}/*** 驗(yàn)證同一個(gè)url數(shù)據(jù)是否相同提交,相同返回true** @param request* @return*/private boolean repeatDataValidator(HttpServletRequest request) {// 獲取POST請(qǐng)求體-body-入?yún)tring params = getRequestBodyParam(request);// 獲取請(qǐng)求路徑String url = request.getRequestURI();Map<String, String> map = new HashMap<>();// 組裝Map key: url、 value:url+請(qǐng)求方法體+時(shí)間map.put(url, params);String nowUrlParams = JSON.toJSONString(map);Object preUrlParams = request.getSession().getAttribute(FIXED_SESSION);//如果上一個(gè)數(shù)據(jù)為null,表示還沒(méi)有訪問(wèn)頁(yè)面if (preUrlParams == null) {//如果上一個(gè)數(shù)據(jù)為null,表示還沒(méi)有訪問(wèn)頁(yè)面request.getSession().setAttribute(FIXED_SESSION, nowUrlParams);return false;} else {//如果上次url+數(shù)據(jù)和本次url+數(shù)據(jù)相同,則表示重復(fù)添加數(shù)據(jù)if (preUrlParams.equals(nowUrlParams)) {log.info("[請(qǐng)求頻繁提交 repeatDataValidator URL :{}; param :{}]", url, params);return true;} else {//如果上次 url+數(shù)據(jù) 和本次url加數(shù)據(jù)不同,則不是重復(fù)提交request.getSession().setAttribute(FIXED_SESSION, nowUrlParams);return false;}}}/*** 獲取請(qǐng)求體-body-入?yún)?* @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("解析入?yún)惓?#xff01;!!", e);} finally {if (bufferedReader != null) {try {bufferedReader.close();} catch (IOException e) {log.error("解析入?yún)惓?#xff01;!!", e);}}}return stringBuffer.toString();} }
3、創(chuàng)建類:配置攔截器路徑(攔截URL規(guī)則);
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 {@Autowiredprivate ResubmitInterceptorUtil resubmitInterceptorUtil;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 配置攔截類registry.addInterceptor(resubmitInterceptorUtil)// 設(shè)置攔截路徑URL.addPathPatterns("/**");}}