上一篇文章写了怎么实现自定义注解
https://blog.csdn.net/qq_29569183/article/details/109310967
在个拦截器中解析并使用注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiIdempotent {
}
下面代码主要分析下如何分析注解
1.handler转换为HandlerMethod 对象
HandlerMethod handlerMethod = (HandlerMethod) handler;
2.获取HandlerMethod 对象的Method属性
Method method = handlerMethod.getMethod();
3.获取Method上的注解
ApiIdempotent methodAnnotation = method.getAnnotation(ApiIdempotent.class)
4.判断注解是否存在,做后续的逻辑处理
拦截器的使用就不赘述了,实现HandlerInterceptor接口重写方法,再基于WebMvcConfigurer 做配置使拦截器生效即可。
public class ApiIdempotentInterceptor implements HandlerInterceptor {
private static final String VERSION_NAME = "version";
private RedisTemplate<String, Object> redisTemplate;
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//如果不是一个接口请求(比如静态资源类的),那么handler就不是一个HandlerMethod
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
//获取目标方法上的幂等注解
ApiIdempotent methodAnnotation = method.getAnnotation(ApiIdempotent.class);
if (methodAnnotation != null) {
// 幂等性校验, 校验通过则放行, 校验失败则抛出异常, 并通过统一异常处理返回友好提示
checkApiIdempotent(request);
}
return true;
}
private void checkApiIdempotent(HttpServletRequest request) {
String version = request.getHeader(VERSION_NAME);
if (StringUtils.isBlank(version)) {// header中不存在token
version = request.getParameter(VERSION_NAME);
if (StringUtils.isBlank(version)) {// parameter中也不存在token
throw new IllegalArgumentException("无效的参数");
}
}
if (!redisTemplate.hasKey(version)) {
throw new IllegalArgumentException("不存在对应的参数");
}
Boolean bool = redisTemplate.delete(version);
if (!bool) {
throw new IllegalArgumentException("没有删除对应的version");
}
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
public ApiIdempotentInterceptor(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
}