第一种 filter 此方法不会拿到类名和方法名
@Component
public class TimeFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("time filter init");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("time filter start");
long start = System.currentTimeMillis();
chain.doFilter(request, response);
System.out.println("time filter 耗时:"+ (System.currentTimeMillis() - start));
System.out.println("time filter finish");
}
public void destroy() {
System.out.println("time filter destroy");
}
}
第二种 基于spring的拦截器 此方法不会拿到请求的参数的值
@Component
public class TimeInterceptor implements HandlerInterceptor {
/**
* 执行前触发
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle");
System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
System.out.println(((HandlerMethod)handler).getMethod().getName());
request.setAttribute("startTime", System.currentTimeMillis());
return true;
}
/**
* 执行后触发 但如果报异常则不会进入此方法
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
Long start = (Long) request.getAttribute("startTime");
System.out.println("time interceptor 耗时:"+ (System.currentTimeMillis() - start));
}
/**
* 执行后触发 无论是否发生异常都会进入此方法
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion");
Long start = (Long) request.getAttribute("startTime");
System.out.println("time interceptor 耗时:"+ (System.currentTimeMillis() - start));
System.out.println("ex is "+ex);
}
}
另外还需要在配置类中注册此组件
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private TimeInterceptor timeInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(timeInterceptor);
}
}
第三种 切面
/**
* nice
*
* @author gaogao
* @date 2018/12/12 18:30.
*/
@Aspect
@Component
public class WebLog implements BaseLogger {
/**
* 任意公共方法的执行:
* execution(public * *(..))
* 任何一个以“set”开始的方法的执行:
* execution(* set*(..))
* AccountService 接口的任意方法的执行:
* execution(* com.xyz.service.AccountService.*(..))
* 定义在service包里的任意方法的执行:
* execution(* com.xyz.service.*.*(..))
* 定义在service包和所有子包里的任意类的任意方法的执行:
* execution(* com.xyz.service..*.*(..))
* 定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:
* execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")
* ***> 最靠近(..)的为方法名,靠近.*(..))的为类名或者接口名,如上例的JoinPointObjP2.*(..))
*
* pointcutexp包里的任意类.
* within(com.test.spring.aop.pointcutexp.*)
* pointcutexp包和所有子包里的任意类.
* within(com.test.spring.aop.pointcutexp..*)
* 实现了MyInterface接口的所有类,如果MyInterface不是接口,限定MyInterface单个类.
* this(com.test.spring.aop.pointcutexp.MyInterface)
* ***> 当一个实现了接口的类被AOP的时候,用getBean方法必须cast为接口类型,不能为该类的类型.
*
* 带有@MyTypeAnnotation标注的所有类的任意方法.
*
* @within(com.elong.annotation.MyTypeAnnotation)
* @target(com.elong.annotation.MyTypeAnnotation) 带有@MyTypeAnnotation标注的任意方法.
* @annotation(com.elong.annotation.MyTypeAnnotation) ***> @within和@target针对类的注解,@annotation是针对方法的注解
*
* 参数带有@MyMethodAnnotation标注的方法.
* @args(com.elong.annotation.MyMethodAnnotation) 参数为String类型(运行是决定)的方法.
* args(String)
*/
//@Pointcut("execution(public * com.e9cloud.aivoice.rest.controller..*.*(..)) && @annotation(com.e9cloud.aivoice.common.log.Loggable)")
@Pointcut("execution(public * com.e9cloud.checkphone.modules.*.controller..*.*(..))")
public void log() {
}
@AfterReturning(value = "log()", returning = "returnVal")
public void log(JoinPoint point, Object returnVal) {
// 获取参数
Object[] params = point.getArgs();
List paramList = Arrays.asList(params);
Object collect = paramList.stream().map(x -> {
if (x != null) {
return x.toString();
} else {
return "null";
}
}).collect(Collectors.toList());
logger.info(StringUtils.join("前端请求参数-----------> ", collect.toString()));
// 获取方法名
String name = point.getSignature().getDeclaringTypeName();
String methodName = point.getSignature().getName();
logger.info(StringUtils.join("调用的控制器-----------> ", name));
logger.info(StringUtils.join("调用的方法名-----------> ", methodName));
// Class> targetClass = point.getTarget().getClass();// 获取目标对象的类名
// Method method = null;
// for (Method mt : targetClass.getMethods()) {
// if (methodName.equals(mt.getName())) {
// method = mt;
// break;
// }
// }
Rsp rsp = (Rsp) returnVal;
if(rsp!=null){
if (rsp.getCode() == 0) {
logger.info(StringUtils.join("后端返回数据-----------> ", rsp.toString()));
} else {
logger.error(StringUtils.join("后端返回数据-----------> ", rsp.toString()));
}
}
}
}