springMVC:HandlerInterceptor拦截器添加系统日志(权限校验)代码收藏

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));
    }

}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值