核心代码:

  


package com.tran.demo.aspect;

import java.lang.reflect.Method;
import java.time.LocalDateTime; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import com.tran.demo.annotation.AuthAnnotation;
import com.tran.demo.enums.ResultEnum;
import com.tran.demo.exception.MyException;
import com.tran.demo.model.User; @Component
@Aspect
public class MyAspect { private Logger log = LoggerFactory.getLogger(MyAspect.class); /**
* 定义切入点,切入点为com.tran.demo.controller下的所有函数
*
* // @Pointcut("@annotation(com.tran.demo.annotation.AuthAnnotation)") 对注解形式方法拦截
*/
@Pointcut("execution(public * com.tran.demo.controller..*.*(..))")
public void aspectLog(){} /**
*
* 前置通知 ,就是到达controller之前
* @param joinPoint
*/
@Before("aspectLog()")
public void doBefore(JoinPoint joinPoint){
log.info("开始执行:{}",LocalDateTime.now());
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest(); log.info("method={}", request.getMethod());
log.info("class={} and method name = {}",joinPoint.getSignature().getDeclaringTypeName(),joinPoint.getSignature().getName()); Object[] args = joinPoint.getArgs();
String[] paramNames = ((CodeSignature)joinPoint.getSignature()).getParameterNames(); for (int i = 0; i < args.length; i++) {
log.info("参数:{},值:{}",paramNames[i],args[i]);
} } /**
* HTTP请求结束时的日志
*/
@After("aspectLog()")
public void doAfter(){ log.info("结束执行:{}",LocalDateTime.now()); } /**
* 接口返回的具体内容
* @param object
*/
@AfterReturning(returning = "object",pointcut = "aspectLog()")
public void doAfterReturn(Object object){ log.info("返回数据:{}", object);
} /**
*
* 进行业务处理,判断是否有权限
*
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around("aspectLog()")
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature(); Method method = methodSignature.getMethod();
AuthAnnotation authAnnotation = method.getAnnotation(AuthAnnotation.class); if (null == authAnnotation) {
log.info("该方法不需要权限,表示没有vip权限即可访问");
return proceedingJoinPoint.proceed();
} log.info("需要的权限:{}", authAnnotation.auth());
String auth = request.getHeader("auth");
log.info("请求头匹配权限:{}",auth);
if (StringUtils.isEmpty(auth) || !auth.equals(authAnnotation.auth())) {
log.info("该请求需要权限");
throw new MyException(ResultEnum.PERMISSION_DENIED);
} return proceedingJoinPoint.proceed();
}
}

 

控制层(Controller):

@RequestMapping("/user")
@RestController
public class UserController { @Autowired
private IUserService userService; @GetMapping("/get/{userid}")
@ResponseBody
@AuthAnnotation(auth="vip")
public List<User> hello(@PathVariable Integer userid) {
Wrapper user = new EntityWrapper<User>();
user.where("userid >= {0}", 10000).and("userid <= {0}", userid);
return userService.selectList(user);
}
}

注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthAnnotation { // 非vip不能访问 user
String auth() default "vip"; }

全局异常处理:

  


@ControllerAdvice
@ResponseBody
public class MyAdvice { private Logger log = LoggerFactory.getLogger(MyAdvice.class); //声明要捕获的异常
@ExceptionHandler(MyException.class)
public Object defultExcepitonHandler(HttpServletRequest request,Exception e) {
log.info("进入增强异常处理:{}",LocalDateTime.now());
log.info("异常信息:{}",e.getMessage());
return e.getMessage();
}
}
这里可以多定义一些常见异常 。。。。。。。。。

枚举:

public enum ResultEnum {
UNKONW_ERROR(401,"未知错误"),
SUCCESS(200,"成功"),
ERROR(402,"失败"),
ID_NOT_IN_SCOPE(403,"id不在范围内"),
PERMISSION_DENIED(405,"权限不足"),
;
private Integer code;
private String msg; ResultEnum(Integer code,String msg) {
this.code = code;
this.msg = msg;
} public Integer getCode() {
return code;
} public String getMsg() {
return msg;
}
}

测试:

后台控制台日志:

  

这里需要注意的是 必须around通过之后才会走 before 注解

spring boot aop 自定义注解 实现 日志检验 权限过滤的更多相关文章

  1. redis分布式锁-spring boot aop+自定义注解实现分布式锁

    接这这一篇redis分布式锁-java实现末尾,实现aop+自定义注解 实现分布式锁 1.为什么需要 声明式的分布式锁 编程式分布式锁每次实现都要单独实现,但业务量大功能复杂时,使用编程式分布式锁无疑 ...

  2. 利用Spring AOP自定义注解解决日志和签名校验

    转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...

  3. spring AOP自定义注解 实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  4. (转)利用Spring AOP自定义注解解决日志和签名校验

    一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...

  5. Spring Boot中自定义注解+AOP实现主备库切换

    摘要: 本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需求:实现关键业务的查询监控,当用Mybatis查询数据时需要从主库切换到备库或者直接连到备库上查询,从而减小主库的 ...

  6. 【Spring】每个程序员都使用Spring(四)——Aop+自定义注解做日志拦截

    一.前言 上一篇博客向大家介绍了Aop的概念,对切面=切点+通知 .连接点.织入.目标对象.代理(jdk动态代理和CGLIB代理)有所了解了.理论很强,实用就在这篇博客介绍. 这篇博客中,小编向大家介 ...

  7. spring boot通过自定义注解和AOP拦截指定的请求

    一 准备工作 1.1 添加依赖 通过spring boot创建好工程后,添加如下依赖,不然工程中无法使用切面的注解,就无法对制定的方法进行拦截 <dependency> <group ...

  8. Spring Boot实现自定义注解

    在Spring Boot项目中可以使用AOP实现自定义注解,从而实现统一.侵入性小的自定义功能. 实现自定义注解的过程也比较简单,只需要3步,下面实现一个统一打印日志的自定义注解: 1. 引入AOP依 ...

  9. 通过AOP自定义注解实现日志管理

    前言: 通过自定义注解和AOP结合的方式,实现日志的记录功能 大致流程:项目运行->用户操作调用业务处理类->通过自定义的注解(我理解为一个切点)->进入到AOP切面类(在这里可以获 ...

随机推荐

  1. 设计简单的VB程序

    1.模拟对话程序 [程序源码] Option Explicit Private Sub Command1_Click() Text2.Text = "" Text1.Text = ...

  2. OnTriggerEnter2D方法

    我两个物体A,B都添加了Circle Collider 2D,并且都勾选了is Trigger,我在A的脚本里用void OnTriggerEnter2D(Collider2D coll)检测碰撞,至 ...

  3. mock数据,尽量随机,1次插入多条

    建表,多设置一个字段id_tmp create table if not exists mall_data.dtw_mall2_adm_customer_d_tmp( id_tmp string co ...

  4. 不同系统、不同存储格式(textfile, parquet)数据的传递

    描述: 本地测试环境hive中有数据,存储格式为textfile,现在要上传到公司开发环境,存储格式为parquet, 如何实现??? tb_textfile表---> local file - ...

  5. 第三次Scrum冲刺————Life in CCSU

    # 第三次Scrum冲刺————Life in CCSU # 一.第三次Scrum任务 小组GitHub地址链接:https://github.com/LoneylittleTeam/Team 个人G ...

  6. IT名词概括与简单了解

    云计算概念 云架构 我看过两本云计算,<云计算><云计算架构技术与实践> 云计算是一个很广的概念,简单的说将互联网中的计算机资源按需分配,提高闲置资源的利用率,需要多少你就购买 ...

  7. Python 找零问题

    #coding = utf-8 def Change_Money(money): print('总金额:'+str(money)+'元') loop=True tmp=[] # 面值列表 单位:元 t ...

  8. centos 终端字体错位个别字母中间有间隔的解决

    问题描述: linux系统:centos 终端:图形界面终端,通过startx启动 现象:通过终端输入的字体有重叠,字母之间的间隔也很大.由于字体安装不正确导致. 解决方法:通过下面字体的安装命令可以 ...

  9. 【转】rem自适应布局

    rem自适应原理 rem是根据html的font-size大小来变化,正是基于这个出发,我们可以在每一个设备下根据设备的宽度设置对应的html字号,从而实现了自适应布局.更多介绍请看这篇文章:rem是 ...

  10. python 解析命令行

    python中的命令行解析最简单最原始的方法是使用sys.argv来实现,更高级的可以使用argparse这个模块.argparse从python 2.7开始被加入到标准库中,所以如果你的python ...