2019独角兽企业重金招聘Python工程师标准>>>

1.spring配置文件配置。

   <!-- 拦截器 --><mvc:interceptors><!-- 日志拦截器 --><bean class="cn.jeeweb.modules.common.interceptor.LogInterceptor" ><property name="openAccessLog" value="${openAccessLog}" /></bean><mvc:interceptor><mvc:mapping path="/**" /><!-- 需排除拦截的地址 --><mvc:exclude-mapping path="/static/**" /><!-- 需排除拦截的地址 --><mvc:exclude-mapping path="/upload/**" /><bean class="cn.jeeweb.core.interceptor.EncodingInterceptor" /></mvc:interceptor></mvc:interceptors>

2.控制类

package cn.jeeweb.modules.common.interceptor;import java.text.SimpleDateFormat;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import cn.jeeweb.core.utils.DateUtils;
import cn.jeeweb.modules.sys.utils.LogUtils;/*** * All rights Reserved, Designed By www.zhisuaninfo.com* * @title: LogInterceptor.java* @package cn.jeeweb.modules.common.interceptor* @description: 访问日志拦截器* @author: gulf* @date: 2018年1月11日 下午12:17:54* @version V1.0* @copyright: 2017 www.zhisuaninfo.com Inc. All rights reserved.**/
public class LogInterceptor implements HandlerInterceptor {private Boolean openAccessLog = Boolean.FALSE;public void setOpenAccessLog(Boolean openAccessLog) {this.openAccessLog = openAccessLog;}private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("ThreadLocal StartTime");/*** 日志对象*/protected Logger logger = LoggerFactory.getLogger(getClass());@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {if (logger.isDebugEnabled()) {long beginTime = System.currentTimeMillis();// 1、开始时间startTimeThreadLocal.set(beginTime); // 线程绑定变量(该数据只有当前请求的线程可见)logger.debug("开始计时: {}  URI: {}", new SimpleDateFormat("hh:mm:ss.SSS").format(beginTime),request.getRequestURI());}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {if (modelAndView != null) {logger.info("ViewName: " + modelAndView.getViewName());}}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {if (openAccessLog) {// 保存日志LogUtils.saveLog(request, handler, ex, null);// 打印JVM信息。if (logger.isDebugEnabled()) {long beginTime = startTimeThreadLocal.get();// 得到线程绑定的局部变量(开始时间)long endTime = System.currentTimeMillis(); // 2、结束时间
//              logger.debug("计时结束:{}  耗时:{}  URI: {}  最大内存: {}m  已分配内存: {}m  已分配内存中的剩余空间: {}m  最大可用内存: {}m",
//                      new SimpleDateFormat("hh:mm:ss.SSS").format(endTime),
//                      DateUtils.formatDateTime(endTime - beginTime), request.getRequestURI(),
//                      Runtime.getRuntime().maxMemory() / 1024 / 1024,
//                      Runtime.getRuntime().totalMemory() / 1024 / 1024,
//                      Runtime.getRuntime().freeMemory() / 1024 / 1024,
//                      (Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory()
//                              + Runtime.getRuntime().freeMemory()) / 1024 / 1024);}}}}

3.工具类

package cn.jeeweb.modules.sys.utils;import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.method.HandlerMethod;import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;import cn.jeeweb.core.utils.CacheUtils;
import cn.jeeweb.core.utils.Exceptions;
import cn.jeeweb.core.utils.IpUtils;
import cn.jeeweb.core.utils.SpringContextHolder;
import cn.jeeweb.core.utils.StringUtils;
import cn.jeeweb.modules.sys.entity.Log;
import cn.jeeweb.modules.sys.entity.Menu;
import cn.jeeweb.modules.sys.entity.User;
import cn.jeeweb.modules.sys.service.ILogService;
import cn.jeeweb.modules.sys.service.IMenuService;
import cn.jeeweb.modules.sys.tags.SysFunctions;public class LogUtils {public static final String CACHE_MENU_NAME_PATH_MAP = "menuNamePathMap";private static ILogService logService = SpringContextHolder.getBean(ILogService.class);private static IMenuService menuService = SpringContextHolder.getBean(IMenuService.class);/*** 保存日志*/public static void saveLog(HttpServletRequest request, String title) {saveLog(request, null, null, title, null);}/*** 保存日志*/public static void saveLog(HttpServletRequest request, String title, String content) {saveLog(request, null, null, title, content);}public static void saveLog(HttpServletRequest request, Object handler, Exception ex, String title) {saveLog(request, handler, ex, title, null);}/*** 保存日志*/public static void saveLog(HttpServletRequest request, Object handler, Exception ex, String title, String content) {User user = UserUtils.getUser();if (user != null && user.getId() != null) {Log log = new Log();log.setTitle(title);log.setType(ex == null ? Log.TYPE_ACCESS : Log.TYPE_EXCEPTION);log.setRemoteAddr(IpUtils.getIpAddr(request));log.setUserAgent(request.getHeader("user-agent"));log.setRequestUri(request.getRequestURI());log.setParams(request.getParameterMap());log.setMethod(request.getMethod());log.setContent(content);// 异步保存日志new SaveLogThread(log, handler, ex).start();}}/*** 保存日志线程*/public static class SaveLogThread extends Thread {private Log log;private Object handler;private Exception ex;public SaveLogThread(Log log, Object handler, Exception ex) {super(SaveLogThread.class.getSimpleName());this.log = log;this.handler = handler;this.ex = ex;}@Overridepublic void run() {// 获取日志标题if (StringUtils.isBlank(log.getTitle())) {String permission = "";if (handler instanceof HandlerMethod) {Method m = ((HandlerMethod) handler).getMethod();RequiresPermissions rp = m.getAnnotation(RequiresPermissions.class);permission = (rp != null ? StringUtils.join(rp.value(), ",") : "");}log.setTitle(getMenuNamePath(log.getRequestUri(), permission));}// 如果有异常,设置异常信息log.setException(Exceptions.getStackTraceAsString(ex));// 如果无标题并无异常日志,则不保存信息if (StringUtils.isEmpty(log.getTitle()) && StringUtils.isEmpty(log.getException())) {return;}// 保存日志信息logService.insert(log);}}/*** 获取菜单名称路径(如:系统设置-机构用户-用户管理-编辑)*/public static String getMenuNamePath(String requestUri, String permission) {String url = StringUtils.substringAfter(requestUri, SysFunctions.getAdminUrlPrefix() + "/");@SuppressWarnings("unchecked")Map<String, String> menuMap = (Map<String, String>) CacheUtils.get(CACHE_MENU_NAME_PATH_MAP);if (menuMap == null) {menuMap = Maps.newHashMap();List<Menu> menuList = menuService.selectList(new EntityWrapper<Menu>());for (Menu menu : menuList) {// 获取菜单名称路径(如:系统设置-机构用户-用户管理-编辑)String namePath = "";if (menu.getParentIds() != null) {List<String> namePathList = Lists.newArrayList();for (String id : StringUtils.split(menu.getParentIds(), "/")) {/** if (Menu.getRootId().equals(id)){ continue; // 过滤跟节点* }*/for (Menu m : menuList) {if (m.getId().equals(id)) {namePathList.add(m.getName());break;}}}namePathList.add(menu.getName());namePath = StringUtils.join(namePathList, "-");}// 设置菜单名称路径if (StringUtils.isNotBlank(menu.getUrl())) {menuMap.put(menu.getUrl(), namePath);} else if (StringUtils.isNotBlank(menu.getPermission())) {for (String p : StringUtils.split(menu.getPermission())) {menuMap.put(p, namePath);}}}CacheUtils.put(CACHE_MENU_NAME_PATH_MAP, menuMap);}String menuNamePath = menuMap.get(url);if (menuNamePath == null) {for (String p : StringUtils.split(permission)) {menuNamePath = menuMap.get(p);if (StringUtils.isNotBlank(menuNamePath)) {break;}}if (menuNamePath == null) {return "";}}return menuNamePath;}
}

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan

转载于:https://my.oschina.net/chendongj/blog/1605606

基于springMVC拦截器实现操作日志统计相关推荐

  1. Spring+SpringMVC+MyBatis深入学习及搭建(十七)——SpringMVC拦截器

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7098753.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十六)--S ...

  2. Java Servlet 过滤器与 springmvc 拦截器的区别?

    前言:在工作中,遇到需要记录日志的情况,不知道该选择过滤器还是拦截器,故总结了一下. servlet 过滤器 定义 java过滤器能够对目标资源的请求和响应进行截取.过滤器的工作方式分为四种 应用场景 ...

  3. 在拦截器里放入参数 controller_干货|SpringMVC拦截器的使用详解

    一.拦截器简介 Spring MVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理. 常见应用场景 1.日志记录:记录请求信息的日志,以便进行信息监控.信 ...

  4. 跨域请求/SpringMVC拦截器

    <!-- 开启允许跨域 --> <mvc:cors> <mvc:mapping path="/**"/> </mvc:cors> S ...

  5. SpringMVC与JSON传值,取值,使用SpringMVC实现文件的上传与下载,SpringMVC拦截器

    一. JSON 1.1 什么是JSON 在实际开发中,通常需要和别的系统交换数据,数据交换的格式通常有XML和JSON等: JSON(JavaScript Object Notation:JavaSc ...

  6. SpringMVC拦截器与Filter过滤器

    SpringMVC拦截器与Filter过滤器 SpringMVC拦截器与Filter过滤器 Spring MVC拦截器的定义 SpringMVC拦截器的配置 SpringMVC拦截器HandlerIn ...

  7. list mybatis 接收 类型_基于mybatis拦截器实现的一款简易影子表自动切换插件

    近期因工作需要,小编基于mybatis拦截器开发了一款简易影子表自动切换插件,可以根据配置实现动态修改表名,即将对原source table表的操作自动切换到对target table表的操作.该插件 ...

  8. SpringMVC拦截器HandlerInterceptor原理及使用

    在使用SpringMVC拦截器的时候,我们接触的最多的便是HandlerInterceptor接口,因为我们所有的自定义拦截器都必须要实现HandlerInterceptor接口,那么就先从Handl ...

  9. SpringMVC拦截器源码解析

    版权声明:本文为CSDN博主「风剑无影」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/dreamcatche ...

最新文章

  1. 全世界最前沿的125个科学问题
  2. 一个SQL的几种写法
  3. 三种插入排序算法:直接插入排序、折半插入排序、希尔插入排序
  4. flash调用摄像头弹出设置框监听
  5. 淘宝数据分析工具汇总
  6. 0x07 MySQL 多表查询
  7. 2016.2.23_导入maven工程遇见的问题【问题】
  8. Clear Type技术
  9. linux分区修复命令,在Linux下成功修复分区表出错
  10. sel4白皮书翻译 | sel4 whitepaper | sel4简介
  11. gcc/g++ 优化标识 -O1 -O2 -O3 -Os -Ofast -Og的作用
  12. Android 小宝宝买装备案列创建
  13. 智慧用电安全管理系统解决方案
  14. 【Excel】用公式提取Excel单元格中的汉字
  15. 将数据库转换为word文档
  16. Windows事件查看器_ID一览表
  17. 单频阻抗匹配:采用四分之一波长变换器
  18. 【材料检测】核磁共振波普NMR氘代试剂的选择
  19. 破解系统密码与重装windows系统
  20. 【教学类-13-03】20221118《数字色块图5*7*8-A4横板-横切》(大班主题《》)

热门文章

  1. python exe是什么_[Python] [转] python.exe和pythonw.exe的区别(区分.py、.pyw、.pyc文件)...
  2. java中system_《java中System类》 | 学步园
  3. python数组plot_Python Matplotlib:动态更新plot-数组长度未知
  4. 天水市一中2021高考成绩查询,天水高中成绩排名2021,天水中考分数线排行榜
  5. mysql if begin end_MySQL存储过程例子,不能在if else里面用begin end否则会报错Erro_MySQL...
  6. android实现博客app,如何从零实现一个你的个人博客Android App?
  7. python非递归前序遍历二叉树_LintCode66:二叉树的前序遍历(python)
  8. python telnet 交互_Python判断telnet通不通的实例
  9. java applet配置_配置Java Applet的运行环境
  10. 计算机二级ms office过关,计算机二级office-计算机二级MS OFFICE过关攻略!附赠练习软件...