spring boot拦截器获取参数(Springboot中基于AOP和拦截器两种方式记录请求日志的对比)
spring boot拦截器获取参数(Springboot中基于AOP和拦截器两种方式记录请求日志的对比)1. 启动项目 @Configuration public class MvcConfigurer implements WebMvcConfigurer { //拦截器 public void addInterceptors(InterceptorRegistry registry){ //增加一个拦截器 registry.addInterceptor(new WebInterceptor()).addPathPatterns("/**"); }} 5.运行测试@Aspect @Component public class WebControllerAop { /** * 指定切点 * 匹配 com.example.demo.controller包及其子包下的所有类的所有方法 */ @Pointcut("execution(public * com.ljt.demo
1.相关依赖文件
<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>
2.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; } }
3.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; } } }
4.拦截器方式
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("/**"); }}
5.运行测试
1. 启动项目
2. 浏览器输入地址: http://localhost:8080/test/hello?param=123456
控制台打印输出:
6.总结:
1. 一个controler方式的执行过程中,拦截器最先开始执行,最后执行完毕。
2. 对于请求参数的获取,AOP方式更加的完整、准确,可以获取到@PathVariable 注解的参数。 如例子中hello就是一个参数。
3. AOP方式对与请求信息获取的更加详细,可以获取到方法名称和所在的类。
完整代码见:
https://gitee.com/freide/springboot