@Target({ElementType.METHOD}) 注解的适用范围
@Retention(RetentionPolicy.RUNTIME) 注解的生命周期
可以使用拦截器Interceptor处理注解,也可以定义切面Aspect
SysLog
加上该注解后,方法调用后生成SysLogEntity,记录方法调用的相关信息(请求参数,方法名,请求用户)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String value() default "操作日志";
/**
* 是否保存请求的参数
*/
public boolean isSaveRequestData() default true;
/**
* 是否保存响应的参数
*/
public boolean isSaveResponseData() default false;
}
SysLogAspect
注解切面
@Before(value = "@annotation(controllerLog)")
public void doBefore(JoinPoint joinPoint, SysLog controllerLog) {
startTime.set(System.currentTimeMillis());
}
/**
* 处理完请求后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "@annotation(controllerLog)" , returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, SysLog controllerLog, Object jsonResult) {
//执行时长(毫秒)
long time = System.currentTimeMillis() - startTime.get();
handleLog(joinPoint, controllerLog, null, jsonResult, time);
}
protected void handleLog(final JoinPoint joinPoint, SysLog controllerLog, final Exception e, Object jsonResult, long time) {
try {
// 获取当前的用户
SysUserEntity loginUser = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
// *========数据库日志=========*//
SysLogEntity sysLog = new SysLogEntity();
//注解上的描述
// 请求的地址
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
sysLog.setIp(ip);
// operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
//请求的参数
Object[] args = joinPoint.getArgs();
if (loginUser != null) {
sysLog.setUserName(loginUser.getUserName());
} else {
sysLog.setUserName(((SysLoginForm) args[0]).getUserName());
}
// if (e != null) {
// operLog.setStatus(BusinessStatus.FAIL.ordinal());
// operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
// }
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
sysLog.setMethod(className + "." + methodName + "()");
sysLog.setTime(time);
sysLog.setCreateTime(new Date());
// 设置请求方式
// sysLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数
getControllerMethodDescription(joinPoint, controllerLog, sysLog, jsonResult);
// 保存数据库
AsyncManager.me().execute(AsyncFactory.recordOper(sysLog));
} catch (Exception exp) {
// 记录本地异常日志
log.error("==前置通知异常==");
log.error("异常信息:{}" , exp.getMessage());
exp.printStackTrace();
}
}
RedisCace
加上该注解后,方法执行前查询Redis 是否存在缓存,如果不存在,则将方法执行后的结果存储进Redis 中。如果存在,则直接返回缓存。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface RedisCache {
/**
* 缓存key
* 若destine为true,存入redis的键为cacheKey的值
* 若destine为false,存入redis的的键为service方法的 cacheKey:userId_id_packageName.className.methodName
*/
String cacheKey() default Constant.SYS_CACHE;
/**
* 数据缓存时间单位s秒 默认5分钟
*/
int cacheTime() default 300;
/**
* 是否使用指定的key
* 若为true,存入redis的键为cacheKey的值
*/
boolean destine() default false;
}
RedisCacheAspect
注解切面
@Slf4j
@Aspect
@Component
public class RedisCacheAspect {
@Autowired
private JedisUtil jedisUtil;
@Pointcut("@annotation(com.tbo.canal.common.annotation.RedisCache)")
public void webAspect() {
}
@SuppressWarnings("unchecked")
@Around("webAspect()")
public Object redisCache(ProceedingJoinPoint pjp) throws Throwable {
//得到类名、方法名和参数
String redisResult;
String className = pjp.getTarget().getClass().getName();
String methodName = pjp.getSignature().getName();
Object[] args = pjp.getArgs();
//得到被代理的方法
Signature signature = pjp.getSignature();
if (!(signature instanceof MethodSignature)) {
throw new IllegalArgumentException();
}
MethodSignature methodSignature = (MethodSignature) signature;
Method method = pjp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
//得到被代理的方法上的注解
String cacheKey = method.getAnnotation(RedisCache.class).cacheKey();
int cacheTime = method.getAnnotation(RedisCache.class).cacheTime();
boolean destine = method.getAnnotation(RedisCache.class).destine();
String key = cacheKey;
if (!destine) {
//根据类名,方法名和参数生成key
key = StringUtils.genKey(cacheKey, className, methodName);
}
log.debug("生成的key[{}]", key);
Object result;
if (!jedisUtil.exists(key)) {
log.debug("缓存未命中");
//缓存不存在,则调用原方法,并将结果放入缓存中
result = pjp.proceed(args);
redisResult = JSON.toJSONString(result);
jedisUtil.setObject(key, redisResult, cacheTime);
} else {
//缓存命中
log.debug("缓存命中");
redisResult = JSONObject.toJSON(jedisUtil.getObject(key)).toString();
//得到被代理方法的返回值类型
Class returnType = method.getReturnType();
result = JSON.parseObject(redisResult, returnType);
}
return result;
}
}
PassToken
加上该注解后,方法执行不需要校验token。
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
boolean value() default true;
}
拦截器
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//如果不是映射到方法直接放行
if(!(handler instanceof HandlerMethod)){
return true;
}
HandlerMethod handlerMethod = (HandlerMethod)handler;
Method method = handlerMethod.getMethod();
if (method.isAnnotationPresent(PassToken.class)) { //方法上面是否有注解?
PassToken passToken = method.getAnnotation(PassToken.class);
if (passToken.value()){
return true;
}else {
HashMap<String,String> hashMap = new HashMap<>();
String token = request.getHeader("token");
try {
boolean ver= TokenUtil.verify(token) ;
if (ver){
return true;
}else{
hashMap.put("msg","token无效");
hashMap.put("code","401");
}
}catch (SignatureVerificationException e){
e.printStackTrace();
hashMap.put("msg","签名不一致");
}catch (TokenExpiredException e){
e.printStackTrace();
hashMap.put("msg","令牌过期异常");
}catch (AlgorithmMismatchException e) {
e.printStackTrace();
hashMap.put("msg", "算法不匹配异常");
}catch (InvalidClaimException e){
e.printStackTrace();
hashMap.put("msg","失效的claim异常");
}catch (Exception e){
e.printStackTrace();
hashMap.put("msg","token无效");
hashMap.put("code","401");
}
String resultJson = JSON.toJSONString(hashMap);
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(resultJson);
return false;
}
}
HashMap<String,String> hashMap = new HashMap<>();
String token = request.getHeader("token");
try {
boolean ver= TokenUtil.verify(token);
if (ver){
return true;
}else {
hashMap.put("msg","token无效");
hashMap.put("code","401");
}
}catch (SignatureVerificationException e){
e.printStackTrace();
hashMap.put("msg","签名不一致");
}catch (TokenExpiredException e){
e.printStackTrace();
hashMap.put("msg","令牌过期异常");
}catch (AlgorithmMismatchException e) {
e.printStackTrace();
hashMap.put("msg", "算法不匹配异常");
}catch (InvalidClaimException e){
e.printStackTrace();
hashMap.put("msg","失效的claim异常");
}catch (Exception e){
e.printStackTrace();
hashMap.put("msg","token无效");
hashMap.put("code","401");
}
String resultJson = JSON.toJSONString(hashMap);
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(resultJson);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}