相关依赖文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--fastjson依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>
Controller测试类
package com.ljt.demo.controller;
@RestController public class DemoController {
@GetMapping("/test/{name}")
public String test(@PathVariable String name,
@RequestParam String param){
name = "hello "+name+" "+param;
return name;
}
}
AOP方式:
新建类WebcontrollerAop,代码如下:
@Aspect @Component public class WebControllerAop { /** * 指定切点 * 匹配 com.example.demo.controller包及其子包下的所有类的所有方法 */ @Pointcut("execution(public * com.ljt.demo.controller.*.*(..))") public void optlog(){ } /** * 前置通知,方法调用前被调用 * @param joinPoint */ @Before("optlog()") public void doBefore(JoinPoint joinPoint){ // System.out.println("我是前置通知,方法执行前调用..."); //获取目标方法的参数信息 Object[] obj = joinPoint.getArgs(); Signature signature = joinPoint.getSignature(); //代理的是哪一个方法 String methodName = signature.getName(); //AOP代理类的名字 String className = signature.getDeclaringTypeName(); MethodSignature methodSignature = (MethodSignature) signature; String[] strings = methodSignature.getParameterNames(); // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest req = attributes.getRequest(); StringBuffer content = new StringBuffer(); content.append("url="+req.getRequestURI()); content.append(" ,paramName=").append(Arrays.toString(strings)); content.append(" ,paramValue=").append( Arrays.toString(joinPoint.getArgs())); content.append( ", clientIp=").append( req.getRemoteAddr()); content.append(" ,HTTP_METHOD=").append(req.getMethod()); content.append(" ,methodName=").append(methodName); content.append(" ,methodClassName=").append(className); System.out.println("AOP方式:"+content); //设置请求开始时间 req.setAttribute("STARTTIME2", System.currentTimeMillis()); } /** * 处理完请求返回内容 * @param ret * @throws Throwable */ @AfterReturning(returning = "ret", pointcut = "optlog()") public void doAfterReturning(Object ret) throws Throwable { // 处理完请求,返回内容 // System.out.println("方法的返回值 : " + ret); } /** * 后置异常通知 * @param jp */ @AfterThrowing("optlog()") public void throwss(JoinPoint jp){ System.out.println("方法异常时执行....."); } /** * 后置最终通知,final增强,不管是抛出异常或者正常退出都会执行 * @param jp */ @After("optlog()") public void after(JoinPoint jp){ // System.out.println("方法最终执行....."); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest req = attributes.getRequest(); //当前时间 long currentTime = System.currentTimeMillis(); long startTime = Long.valueOf(req.getAttribute("STARTTIME2").toString()); System.out.println("AOP方式请求耗时:"+(currentTime - startTime)+"ms"); } /** * 环绕通知,环绕增强,相当于MethodInterceptor * @param pjp * @return */ @Around("optlog()") public Object arround(ProceedingJoinPoint pjp) { try { Object o = pjp.proceed(); return o; } catch (Throwable e) { e.printStackTrace(); return null; } } }
拦截器方式:
1.新建拦截器类WebInterceptor实现HandlerInterceptor接口
public class WebInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //请求路劲 String url = request.getRequestURI(); //获取请求参数信息 String paramData = JSON.toJSONString(request.getParameterMap(),SerializerFeature.DisableCircularReferenceDetect,SerializerFeature.WriteMapNullValue); //获取请求客户都IP String clientIp = request.getRemoteAddr(); //请求方法 String methodName = request.getMethod(); // String requestType = request.getHeader("X-Requested-With"); StringBuffer content = new StringBuffer(); content.append("url="+url); content.append(" ,paramData=").append(paramData); content.append( ", clientIp=").append(clientIp); content.append(" ,HTTP_METHOD=").append(methodName); System.out.println("拦截器方式:"+content); //设置请求开始时间 request.setAttribute("STARTTIME", System.currentTimeMillis()); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { //controller 方法处理完毕后,调用此方法 } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { //页面渲染完毕后调用次方法,通常用来清除某些资源,类似java中的finnally int status = response.getStatus(); //当前时间 long currentTime = System.currentTimeMillis(); long startTime = Long.valueOf(request.getAttribute("STARTTIME").toString()); System.out.println("拦截器方式请求耗时:"+(currentTime - startTime)+"ms"); } }
2.添加拦截器
@Configuration
public class MvcConfigurer implements WebMvcConfigurer {
//拦截器
public void addInterceptors(InterceptorRegistry registry){
//增加一个拦截器
registry.addInterceptor(new WebInterceptor()).addPathPatterns("/**");
}
}
运行测试
- 启动项目
- 浏览器输入地址: http://localhost:8080/test/hello?param=123456
控制台打印输入:
总结:
- 一个controler方式的执行过程中,拦截器最先开始执行,最后执行完毕。
- 对于请求参数的获取,AOP方式更加的完整、准确,可以获取到@PathVariable 注解的参数。 如例子中hello就是一个参数。
- AOP方式对与请求信息获取的更加详细,可以获取到方法名称和所在的类。
完整代码见:
https://gitee.com/freide/springboot