1.自定义注解类
自定义注解需要用到元注解,如@Target、@Retention、@Document、@Inherited.
@Target:
@Target 指定注解的作用范围,该注解有以下属性值
1.ElementType.TYPE //作用于类、接口、枚举,但不能是注解
2.ElementType.FIELD //作用于字段、枚举
3.ElementType.METHOD //作用于方法、不能是构造方法
4.ElementType.PARAMETER //作用于方法的参数
5.ElementType.CONSTRUCTOR //作用于构造函数
6.ElementType.LOCAL_VARIABLE // 局部变量,作用于本地变量或者catch语句
7.ElementType.ANNOTATION_TYPE //作用于注解
8.ElementType.PACKAGE / /作用于包
@Retention:
@Retention 指定注解的保留策略 三个
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
@Retention(RetentionPolicy.RUNTIME) //在运行时可以通过反射获取到,JVM会读取注解,同时保存在class文件中
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
编写一个自定义注解:
/**
* 自定义注解
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation{
/**
* 拦截时间 单位为秒 默认值1秒
*/
int time() default 1;
}
使用,在方法上添加上注解
@ResponseBody
@PostMapping("doLogin")
@MyAnnotaton(time = 30)
public SaResult doLogin(@RequestBody User user) {
return userServerService.doLogin(user);
}
2.配置拦截器
/**
* 拦截器配置类
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
public LoginInterceptor getInterceptorBean(){
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
String[] addPathPattern = {
"/auth/doLogin"
};
String[] excludePathPattern={
"/info/addXmlInfo",
"/auth/registry",
};
registry.addInterceptor(getInterceptorBean()).addPathPatterns(addPathPattern).excludePathPatterns(excludePathPattern);
WebMvcConfigurer.super.addInterceptors(registry);
}
}
3.使用拦截器防止重复请求功能
首次访问请求,登录成功,会把这次的Ip地址和路径记录作为key,保存到session中,并设置过期时间,当第二次访问时,会拿着Ip地址和路径到session找,找到了就把请求拦截下来,返回信息。
/**
* 认证登录拦截
*/
public class LoginInterceptor implements HandlerInterceptor {
private static final Logger log = LoggerFactory.getLogger(LoggerFactory.class);
/**
* 进入controller层之前拦截请求
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof ResourceHttpRequestHandler) {
// 静态资源不做权限处理
return true;
}
// 用户IP地址
String addr = request.getRemoteAddr();
// 访问的url地址
String requestURI = request.getRequestURI();
HandlerMethod handlerMethod = (HandlerMethod) handler;
//得到方法上的DuplicateCommitLimit注解
DuplicateCommitLimit duplicateCommitLimit =
handlerMethod.getMethodAnnotation(DuplicateCommitLimit.class);
if (duplicateCommitLimit != null) {
String key = "duplicate_commit_" + requestURI + "_" + addr);
boolean isLimited = false;
Object object = request.getSession().getAttribute(key);
if (null == object) {
log.info("用户IP={},url地址={} 首次登录", addr, requestURI);
} else {
isLimited = true;
}
if (isLimited) {
sendMsg(response);//返回被拦截提示信息
return false;
} else {
HttpSession session = request.getSession();
session.setMaxInactiveInterval(duplicateCommitLimit.time());
session.setAttribute(msgVO.getKey(), true);
}
}
return true;
}
/**
* 设置请求的响应信息
*
* @param response
*/
private void sendMsg(HttpServletResponse response) {
SaResult saResult = new SaResult();
saResult.setCode(4000);
saResult.setMsg("请勿重复提交或者操作过于频繁!");
ResponseUtils.renderJson(response, saResult.toString());
}
}