springMVC:HandlerInterceptor拦截器添加系统日志(权限校验)代码收藏
2018-03-18 19:44
363 查看
public class RequestLogIntercepter implements HandlerInterceptor { private Logger log = LoggerFactory.getLogger(RequestLogIntercepter.class); @Autowired private ISysMenuDao sysMenuDao; @Autowired private ISysLogDao sysLogDao; /** * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。该方法将在整个请求完成之后, * 也就是DispatcherServlet渲染了视图执行, * 这个方法的主要作用是用于清理资源的,当然这个方法也只能在当前这个Interceptor的preHandle方法的返回值为true时才会执行。 */ @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { // TODO Auto-generated method stub } /** * 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。postHandle是进行处理器拦截用的, * 它的执行时间是在处理器进行处理之 * 后,也就是在Controller的方法调用之后执行,但是它会在DispatcherServlet进行视图的渲染之前执行, * 也就是说在这个方法中你可以对ModelAndView进行操 * 作。这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor拦截器该方法反而会后调用, * 这跟Struts2里面的拦截器的执行过程有点像, * 只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法, * Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor * 或者是调用action,然后要在Interceptor之前调用的内容都写在调用invoke之前, * 要在Interceptor之后调用的内容都写在调用invoke方法之后。 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView mv) throws Exception { //判断是否是登录操作,且在登录成功的情况下,缓存功能数据 String url = request.getRequestURI().toString(); int lastIndexByApi = url.lastIndexOf("/api"); String dataUrl = ""; if(lastIndexByApi != -1){ dataUrl = url.substring(lastIndexByApi + 5); } if("login/dologin.action".equals(dataUrl)){//登录url //判断是否登录成功 HttpSession session = request.getSession(); SysUserVo user = (SysUserVo) session.getAttribute(Constant.CURRENT_SYS_USER); if(user == null){ //登录失败 return; } //获取所有的功能数据 List<SysMenuDto> sysMenuDtos = sysMenuDao.getAllSysMenu(); if(sysMenuDtos != null){ //缓存功能数据 CacheManager cacheManager = EhCacheUtil.manager; Cache cache = cacheManager.getCache(Constant.EHCACHE_SYS_MENU); if(cache == null){ cacheManager.addCache(Constant.EHCACHE_SYS_MENU); cache = cacheManager.getCache(Constant.EHCACHE_SYS_MENU); } Map<String, SysMenuDto> mapUrlKey = new HashMap<>(); Map<String, SysMenuDto> mapApiUrlKey = new HashMap<>(); Map<String, SysMenuDto> mapIdKey = new HashMap<>(); for (SysMenuDto sysMenuDto:sysMenuDtos){ mapIdKey.put(String.valueOf(sysMenuDto.getId()),sysMenuDto); String path = sysMenuDto.getMenuPath(); int type = sysMenuDto.getType(); if(path != null && path.indexOf(".html") != -1 && path.lastIndexOf("/") != -1 && type == 1){//是一个完整路径 path = path.substring(0,path.lastIndexOf("/")); mapApiUrlKey.put(path,sysMenuDto); } mapUrlKey.put(sysMenuDto.getMenuPath(),sysMenuDto); } cache.put(new Element(Constant.EHCACHE_SYS_MENU_ALL,sysMenuDtos)); cache.put(new Element(Constant.EHCACHE_SYS_MENU_ALL_URLKEY,mapUrlKey)); cache.put(new Element(Constant.EHCACHE_SYS_MENU_ALL_APIURLKEY,mapApiUrlKey)); cache.put(new Element(Constant.EHCACHE_SYS_MENU_ALL_IDKEY,mapIdKey)); }else{ log.error("添加系统日志时,添加sys_menu表缓存数据出现问题,未查询到数据!"); } //添加登录系统日志 addSysLog(request,dataUrl,"登录系统"); } } /** * preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进行调用, * SpringMVC中的Interceptor拦截器是链式的,可以同时存在 * 多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的执行, * 而且所有的Interceptor中的preHandle方法都会在 * Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中断的, * 这种中断方式是令preHandle的返 回值为false,当preHandle的返回值为false的时候整个请求就结束了。 */ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception { // 输出请求日志 log.debug("Request Start ------------------------------------------------"); log.debug("Request Info: [IP = {}] , [Time = {}] , [Method = {}] , [URI = {}] ,[Params = {}],[userAgent = {}] ", IPReqUtil.getIp(request), sdf.format(new Date()), request.getMethod(), request.getRequestURI(), request.getParameterMap(), request.getHeader("user-agent")); String url = request.getRequestURL().toString(); log.info("---> url : " + url); int lastIndexByApi = url.lastIndexOf("/api"); String dataUrl = ""; if(lastIndexByApi != -1){ dataUrl = url.substring(lastIndexByApi + 5); }else{ log.error("添加系统日志发生问题,请求url异常:" + url); return true; } //http://localhost:8080/api/user/checkSysUserOnline //需要记录日志的url有如下三种情况 //1.登录、退出 if("login/logoutSystem".equals(dataUrl)){//退出url //添加登录系统日志 addSysLog(request,dataUrl,"退出系统!"); return true; } //2.页面url //3.页面功能按钮url HttpSession session = request.getSession(); SysUserVo user = (SysUserVo) session.getAttribute(Constant.CURRENT_SYS_USER); if(user != null){ //添加登录系统日志 addSysLog(request,dataUrl,""); } return true; } private void addSysLog(HttpServletRequest request,String url,String content){ SysLogDto sysLogDto = null; try { AccountDto accountDto = (AccountDto) SecurityUtils.getSubject().getSession().getAttribute(Constant.CURRENT_EMPLOY); String username = accountDto == null ? null : accountDto.getUsername(); String empId = accountDto == null ? null : accountDto.getEmployeeId(); // String empId="test"; if(StringUtils.isBlank(empId)){ empId = username; log.error("添加系统日志异常,操作人id为空!"); } Map<String, SysMenuDto> mapUrlKey= (Map<String, SysMenuDto> ) EhCacheUtil.get(Constant.EHCACHE_SYS_MENU,Constant.EHCACHE_SYS_MENU_ALL_URLKEY); Map<String, SysMenuDto> mapApiUrlKey= (Map<String, SysMenuDto> ) EhCacheUtil.get(Constant.EHCACHE_SYS_MENU,Constant.EHCACHE_SYS_MENU_ALL_APIURLKEY); sysLogDto = new SysLogDto(); if(StringUtils.isNotBlank(content)){ sysLogDto.setOprationFunction(content); }else{ if(mapUrlKey != null ){ SysMenuDto sysMenuDto = mapUrlKey.get(url) == null ? mapApiUrlKey.get(url) : mapUrlKey.get(url); if(sysMenuDto == null){ return; } if(0 == sysMenuDto.getType()){//访问的页面 sysLogDto.setOprationPage(sysMenuDto.getMenuName()); }else if(1 == sysMenuDto.getType()){//访问的页面功能 Map<String, SysMenuDto> mapIdKey= (Map<String, SysMenuDto> ) EhCacheUtil.get(Constant.EHCACHE_SYS_MENU,Constant.EHCACHE_SYS_MENU_ALL_IDKEY); if(mapIdKey != null){ int id = sysMenuDto.getMenuParentId(); sysLogDto.setOprationPage(mapIdKey.get(String.valueOf(id)).getMenuName()); sysLogDto.setOprationFunction(sysMenuDto.getMenuName()); }else{ log.error("添加系统日志异常,获取系统功能菜单EHCACHE_SYS_MENU_ALL_IDKEY缓存失败!"); } } }else{ log.error("添加系统日志异常,获取系统功能菜单EHCACHE_SYS_MENU_ALL_URLKEY缓存失败!"); return; } } sysLogDto.setId(String.valueOf(GloabalIdGenerator.generatId("sys_log"))); sysLogDto.setIp(IPReqUtil.getIp(request)); sysLogDto.setUserId(empId); sysLogDto.setOprationTime(new Date()); sysLogDto.setOprationUrl(url); } catch (InvalidSessionException e) { e.printStackTrace(); } //添加操作日志 int addNum = sysLogDao.insert(sysLogDto); if(addNum != 1){ log.error("添加系统操作日志失败,操作详情如下:" + sysLogDto.toString()); } } public static void main(String[] args){ String url = "http://localhost:8080/api/user/checkSysUserOnline"; int index = url.lastIndexOf("/api"); System.out.println(index); System.out.println(url.substring(index+5)); } }
相关文章推荐
- Winform开发框架之权限管理系统改进的经验总结(4)-一行代码实现表操作日志记录
- asp.net中使用Global.asax文件中添加应用出错代码,写入系统日志文件或数据库
- 公司员工没有管理员权限怎么办 C#文件夹、文件添加权限 C#读取windows系统日志 C#设置环境变量
- asp.net中使用Global.asax文件中添加应用出错代码,写入系统日志文件或数据库
- asp.net中使用Global.asax文件中添加应用出错代码,写入系统日志文件或数据库
- 公司员工没有管理员权限怎么办 C#文件夹、文件添加权限 C#读取windows系统日志 C#设置环境变量
- 系统日志的操作权限
- Android常用代码之普通及系统权限静默安装APK
- mymoni3——具体代码~添加权限依赖 + 页面布局 + 封装类、工具类
- 有意思的代码--利用系统信号切换日志模式
- iOS利用代码添加事件到系统日历中
- Android 一行代码搞定将错误日志放入到sd卡中且不需要任何权限,适配到android7.0
- Android4.0应用开发中添加系统权限无法访问SD卡
- 简单权限系统基于shiro-springmvc-spring-mybatis(学习笔记2)
- 更好的添加到某某书签某某收藏的代码
- 【视频分享】Liger UI实战集智建筑project管理系统配商业代码(打印报表、角色式权限管理)
- 添加有源码apk到系统目录下编译(使应用拥有系统应用权限)
- 代码设置SPList权限(添加SPGroup)
- 权限管理系统(用户信息管理模块业务组件实现代码,带注解)
- Windows 不能在 本地计算机 启动 OracleDBConsoleorcl。有关更多信息,查阅系统事件日志。如果这是非 Microsoft 服务,请与服务厂商联系,并参考特定服务错误代码 2。