spring boot 拦截器 或 Spring AOP 方式记录请求日志
为什么80%的码农都做不了架构师?>>>
选择使用拦截器实现,在实现中遇到两个个问题:
a. POST请求 @RequestBody 传的参数不知怎么获取?
b. 返回结果如何获取?
c.拦截器中service 无法注入;(已解决)
不知道有没有人遇到这种情况,拦截器没有解决上述问题,后来使用 spring AOP 处理。
《一》拦截器方式
@Configuration
public class OptPermissionHandlerInterceptor extends HandlerInterceptorAdapter {private Logger logger = LoggerFactory.getLogger(OptPermissionHandlerInterceptor.class);@Autowiredprivate OptLogService optLogService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {} @SuppressWarnings("rawtypes")@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception {try {if (handler instanceof HandlerMethod) {HandlerMethod handlerMethod = (HandlerMethod) handler;String beanName = handlerMethod.getBean().getClass().toString();String methodName = handlerMethod.getMethod().getName();String uri = request.getRequestURI();String remoteAddr = getIpAddr(request);String sessionId = request.getSession().getId();String user = (String) request.getSession().getAttribute(Constant.USER);String method = request.getMethod();System.out.println("请求方式为="+method);Map params = null;if("POST".equals(method)){//........}else{params = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);}// 取不到值MethodParameter[] mps = ((HandlerMethod) handler).getMethodParameters();for(MethodParameter mp : mps){System.out.println(mp.getParameterName() + " -- "+ mp.getParameterType());}// 取不到值Map<String, String[]> params2 = request.getParameterMap(); //拦截器中optLogService 没有注入成功时,重新获取;if (optLogService == null) {System.out.println("optLogService is null !!!");BeanFactory factory =WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());optLogService = (OptLogService) factory.getBean("optLogService");}optLogService.saveOptLog(.....);}} catch (Exception e) {logger.error("用户操作日志记录异常", e);}super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {}//获取客户端IPprivate String getIpAddr(HttpServletRequest request) {String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return ip;}
}
《二》Spring AOP方式(面向切面)
1.在pom.xml 中引入spring aop 依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
2.在 application.properties 文件中添加:
spring.aop.auto=true
spring.aop.proxy-target-class=false
3.实现切面
@Aspect
@Component
public class WebRequestLogAspect {private static Logger logger = LoggerFactory.getLogger(WebRequestLogAspect.class);private ThreadLocal<OperatorLog> tlocal = new ThreadLocal<OperatorLog>();@Autowiredprivate OptLogService optLogService;@Pointcut("execution(public * com.whitelover.test..*.create*(..))")public void webRequestLog() {}// @Order(5)@Before("webRequestLog()")public void doBefore(JoinPoint joinPoint) {try {long beginTime = System.currentTimeMillis();// 接收到请求,记录请求内容ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String beanName = joinPoint.getSignature().getDeclaringTypeName();String methodName = joinPoint.getSignature().getName();String uri = request.getRequestURI();String remoteAddr = getIpAddr(request);String sessionId = request.getSession().getId();String user = (String) request.getSession().getAttribute("user");String method = request.getMethod();String params = "";if ("POST".equals(method)) {Object[] paramsArray = joinPoint.getArgs();params = argsArrayToString(paramsArray);} else {Map<?, ?> paramsMap = (Map<?, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);params = paramsMap.toString();}logger.debug("uri=" + uri + "; beanName=" + beanName + "; remoteAddr=" + remoteAddr + "; user=" + user+ "; methodName=" + methodName + "; params=" + params);OperatorLog optLog = new OperatorLog();optLog.setBeanName(beanName);optLog.setCurUser(user);optLog.setMethodName(methodName);optLog.setParams(params != null ? params.toString() : "");optLog.setRemoteAddr(remoteAddr);optLog.setSessionId(sessionId);optLog.setUri(uri);optLog.setRequestTime(beginTime);tlocal.set(optLog);} catch (Exception e) {logger.error("***操作请求日志记录失败doBefore()***", e);}}// @Order(5)@AfterReturning(returning = "result", pointcut = "webRequestLog()")public void doAfterReturning(Object result) {try {// 处理完请求,返回内容OperatorLog optLog = tlocal.get();optLog.setResult(result.toString());long beginTime = optLog.getRequestTime();long requestTime = (System.currentTimeMillis() - beginTime) / 1000;optLog.setRequestTime(requestTime);System.out.println("请求耗时:" + optLog.getRequestTime() + optLog.getUri() + " ** " + optLog.getParams() + " ** "+ optLog.getMethodName());System.out.println("RESPONSE : " + result);optLogService.saveLog(optLog);} catch (Exception e) {logger.error("***操作请求日志记录失败doAfterReturning()***", e);}}/*** 获取登录用户远程主机ip地址* * @param request* @return*/private String getIpAddr(HttpServletRequest request) {String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return ip;}/*** 请求参数拼装* * @param paramsArray* @return*/private String argsArrayToString(Object[] paramsArray) {String params = "";if (paramsArray != null && paramsArray.length > 0) {for (int i = 0; i < paramsArray.length; i++) {Object jsonObj = JSON.toJSON(paramsArray[i]);params += jsonObj.toString() + " ";}}return params.trim();}}
spring aop参考网站:
http://blog.didispace.com/springbootaoplog/
@PointCut 表达式参考网站:
http://www.cnblogs.com/lic309/p/4079194.html
转载于:https://my.oschina.net/gmd/blog/704372
spring boot 拦截器 或 Spring AOP 方式记录请求日志相关推荐
- Spring Boot拦截器(WebMvcConfigurerAdapter)
直接按我的步骤走都没有问题: 1 配置自定义的拦截器: package com.configs;import org.slf4j.Logger; import org.slf4j.LoggerFact ...
- 使用spring boot拦截器实现青少年模式
思路方法一: 便用Spring Boot拦截器采累计在线时间采实现青少年模式的步骤,可以参考以卜步骤: 1.创建一个拦截器类,实现Handlerlnterceptor 接口. 2.在拦截器类中,定义一 ...
- 解决Spring Boot 拦截器注入service为空的问题
解决Spring Boot 拦截器注入service为空的问题 参考文章: (1)解决Spring Boot 拦截器注入service为空的问题 (2)https://www.cnblogs.com/ ...
- Spring Boot拦截器(Interceptor)详解
写了那么久的博客,始于Python爬虫,目前专于Java学习,终于有了属于自己的小窝,欢迎各位访问我的个人网站. 文章目录 Interceptor 介绍 Interceptor 作用 自定义 Inte ...
- Spring Boot 拦截器无效,不起作用
这个问题一般是解决WebMvcConfigurerAdapter过时问题造成的.导致这个问题可能有两个原因:一个是拦截器写错了,另一个是拦截器配置错了. 1.需求是这样的 拦截所有的api请求,判断其 ...
- spring boot 拦截器获取controller返回的数据_高级码农Spring Boot实战与进阶之过滤器和拦截器的使用及其区别...
众所周知的Spring Boot是很优秀的框架,它的出现简化了新Spring应用的初始搭建以及开发过程,大大减少了代码量,目前已被大多数企业认可和使用.这个专栏将对Spring Boot框架从浅入深, ...
- Spring boot拦截器登录检查
拦截器 进行登录检查 从登录页面跳转到成功页面之后 为了防止表单重复提交 配置视图映射,利用重定向到成功页面 此时,在浏览器直接输入,配置的视图映射地址 也可以直接映射.跳转到成功页面 登录页面,也就 ...
- Spring Boot 拦截器
(一)拦截器概述 1.1拦截器介绍 拦截器的作用类似于Servlet 中的Filter,都可以用于对处理器进行预处理和后处理.在Spring MVC 与Spring Boot 中使用拦截器一般是实现H ...
- java 拦截器响应中取所有参数,spring boot拦截器中获取request post请求中的参数
最近有一个需要从拦截器中获取post请求的参数的需求,这里记录一下处理过程中出现的问题. 首先想到的就是request.getParameter(String )方法,但是这个方法只能在get请求中取 ...
- spring boot拦截器 过滤器
1.拦截器 登录拦截 自定义拦截路径 //全局配置继承WebMvcConfigurer接口 @Configuration public class MyHandler implements WebMv ...
最新文章
- MFC Ribbon风格界面去掉左上的Quick Access Toolbar小三角
- node--CommonJS
- iOS 多线程基础之 NSThread
- 自动化运维-云装机实践
- 图的广度优先搜索(bfs)以及深度优先搜索(dfs)
- android wifi 通讯录,通过wifi和gmail从symbian手机中将名片夹(通讯录)导入到android手机 | 古意人...
- 怎么通过java去调用并执行shell脚本以及问题总结
- VMware虚拟机不能连接USB的问题
- 按键精灵手机助手错误:at tempt to compare nu11 with number
- 软件环境常识 --dev sit uat
- 软件测试好学吗?前期比较容易,后期有一定难度
- 2.2、项目管理知识体系构成
- saas、paas、laas 的概念与区别
- 深入学习用 Go 编写 HTTP 服务器
- 显示商品分类列表页面
- 不连接显示器或者HDMI欺骗器来 使用Moonlight串流游戏
- 【深度残差收缩网络】Deep-Residual-Shrinkage-Networks模型+代码
- 开怀大笑有助于使心中的郁闷情绪得到疏导
- Android实习周记:第一周,井底之蛙上岸
- WLAN网络配置,vlan内漫游