一种通过切面编程来自定义注解,以下代码demo是通过自定义注解对加密参数进行验证的过程,不用关心代码的业务过程,直接看通过@Aspect是如何自定义注解的,有了以下代码,springboot工程中的主类还需要加
@EnableAspectJAutoProxy 注解
直接看代码:
@Documented
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SignCheck {
}
@Slf4j
@Aspect
@Configuration
public class SignCheckAspect {
private String secret = "123123";
private Long expire = (1000 * 60) * 2L;
// 定义切点方法
@Pointcut("@annotation(com.ecej.ecejcomponents.basic.anotation.SignCheck)")
public void pointCut() {
}
@Around("pointCut()")
public void around(ProceedingJoinPoint joinPoint) {
String signStr = RequestUtils.getHeader("sign");
// 拦截的类名
Class clazz = joinPoint.getTarget().getClass();
// 拦截的方法
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
SignCheck annotation = method.getAnnotation(SignCheck.class);
if (annotation != null) {
log.info("类:" + clazz + " 方法:" + method + " 获取到注解");
}
Object[] values = joinPoint.getArgs();
if (values.length == 0) {
return;
}
//目前只支持post请求
Object vo = values[0];
Map<String, Object> map = BeanUtil.beanToMap(vo);
String paramSign = ParamsEncodeUtil.createSign(map, secret);
if (!signStr.equals(paramSign)) {
ExceptionUtils.throwBusinessException(ResultCodeEnum.MARKETING_INTERFACE_AUTH_FAIL_ERROR);
}
checkExpire(map.get("timestamp"));
}
//接口过期时间校验
public void checkExpire(Object timestamp) {
long signTime = Long.parseLong(timestamp.toString());
long nowTime = System.currentTimeMillis();
long mx = nowTime - signTime;
if (mx > expire) {
ExceptionUtils.throwBusinessException(ResultCodeEnum.MARKETING_INTERFACE_AUTH_EXPIRE_ERROR);
}
}
}