描述:
在项目中我想在一个方法上添加个自定义注解,然后aop就可以拦截这个方法做有效验证,验证过了后在传参的时候又自定义个注解来解析token里面的值,这样我就不用每个方法都写相同的获取方法了
首先是验证注解:
1:创建注解类
package com.ld.api.target;
import java.lang.annotation.*;
/**
* @author likui
* @date 2019/11/25 002513:58
*/
@Target({ElementType.FIELD, ElementType.METHOD}) //声明自定义的注解使用在方法上
@Retention(RetentionPolicy.RUNTIME)//注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
@Documented
public @interface LoginUser {
}
2:创建aop拦截类
/**
* @author likui
* @date 2019/11/25 002514:20
*/
@Slf4j
@Aspect // 这个注解表明 使用spring 的aop,需要开启aop <!--开启AOP自动代理 --><aop:aspectj-autoproxy />
@Component
public class LoginUserAspect {
@Pointcut("@annotation(com.ld.api.target.LoginUser)")
public void pointcutLoginUser() {
}
@Before("pointcutLoginUser()")//该注解表示拦截添加了@LoginUser注解的方法体
public void LoginUser() throws Exception {
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
String token = request.getHeader("token");
System.out.println(token.isEmpty());
if (token==null || token.isEmpty()) {
throw new Exception("token失效");
}
}
}
说明:主要用于有效值的认证 LoginUser方法体可以根据自己的业务逻辑改变
3:捕获抛出的异常信息
@ControllerAdvice
public class ExceptionConfig {
/**
* API统一异常处理
**/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResultEntity jsonApiErrorHandler(HttpServletRequest request, Exception e) {
return ResultEntity.error("异常请稍后重试");
}
}
4:使用
解析器注解:
1:创建注解类
/**
* @author likui
* @date 2019/11/25 002517:02
* 1.CONSTRUCTOR:用于描述构造器
* 2.FIELD:用于描述域
* 3.LOCAL_VARIABLE:用于描述局部变量
* 4.METHOD:用于描述方法
* 5.PACKAGE:用于描述包
* 6.PARAMETER:用于描述参数
* 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
*/
@Target({ElementType.PARAMETER, ElementType.LOCAL_VARIABLE}) //声明自定义的注解使用在方法上
@Retention(RetentionPolicy.RUNTIME)//注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
public @interface LoginUserAnnotation {
}
2:创建解析器类
/**
* @author likui
* @date 2019/11/25 002522:09
* 有@LoginUserAnnotation注解的方法参数,注入当前登录用户
*
*/
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(LoginUserAnnotation.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
//获取用户ID
Object object = nativeWebRequest.getAttribute("token", RequestAttributes.SCOPE_REQUEST);
if (object == null) {
return null;
}
User user = new User();
user.setName("周三干");
return user;
}
}
3:配置读取LoginUserHandlerMethodArgumentResolver类(重要)
/**
* @author likui
* @date 2019/11/25 002522:55
*/
@Configuration
public class ApplicationConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new LoginUserHandlerMethodArgumentResolver());
}
}
4:使用
这样就可以直接用user对象里面的值