ssm框架在当今项目中是比较常用的,而我们也经常需要用到拦截器做资源和权限管理,譬如登陆拦截等等,最近几天领导要求我用拦截器做一个操作日志的记录,下面我给大家分享一下我的代码以及心得。
SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法。preHandle在业务处理器处理请求之前被调用,
postHandle在业务处理器处理请求执行完成后,生成视图之前执行,afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 。所以要想实现自己的权限管理逻辑,需要继承HandlerInterceptorAdapter并重写其三个方法。
(1) 首先我们要注册拦截器并书写拦截
@Bean public GlobalInterceptor globalInterceptor(){ return new GlobalInterceptor(); } @Bean public InsuranceLoginterceptor insuranceLoginterceptor(){ return new InsuranceLoginterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(globalInterceptor()).addPathPatterns("/**").excludePathPatterns("/api/**").excludePathPatterns("/staitc/**"); registry.addInterceptor(insuranceLoginterceptor()).addPathPatterns("/api/yingu/insurance/updateInsuranceEmpNum"); super.addInterceptors(registry); }(2)实现HandlerInterceptorAdapter自定义拦截器,并重写方法
@Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { log.info("进入调单方法controller层之前"); String insuranceId = httpServletRequest.getParameter("insuranceId"); try { FanHuaBack fanHuaBackOld = insureListService.getinsure(insuranceId); String oldData = JSON.toJSONString(fanHuaBackOld); httpServletRequest.setAttribute("dataBefore", oldData); super.preHandle(httpServletRequest,httpServletResponse,o); } catch (Exception e) { log.error("车险投保信息查询异常", e.getMessage()); } finally { return true; } } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { log.info("进入调单方法controller层之后-----------日志记录开始"); InsuranceOperatLog insuranceOperatLog = new InsuranceOperatLog(); int status = 0; try { String requestURI = httpServletRequest.getRequestURI(); String insuranceId = httpServletRequest.getParameter("insuranceId"); String empNo = httpServletRequest.getParameter("empNo"); String empName = httpServletRequest.getParameter("empName"); int opeStatus = (int) httpServletRequest.getAttribute("status"); FanHuaBack fanHuaBackNew = insureListService.getinsure(insuranceId); String newData = JSON.toJSONString(fanHuaBackNew); String oldData = (String) httpServletRequest.getAttribute("dataBefore"); Map<String, String> map = new HashMap<>(); map.put("empNum", empNo); map.put("empName", empName); map.put("insuranceId", insuranceId); String reqObj = JSON.toJSONString(map); insuranceOperatLog.setInsuranceId(insuranceId); insuranceOperatLog.setCreateTime(DateUtil.format(new Date(), DateUtil.Formatter.yyyyMMddHHmmss)); insuranceOperatLog.setDataBefore(oldData); insuranceOperatLog.setDataAfter(newData); insuranceOperatLog.setReq_json(reqObj); insuranceOperatLog.setReq_url(requestURI); insuranceOperatLog.setOperatorType("调单"); insuranceOperatLog.setStatus(opeStatus == 1 ? "成功" : "失败"); SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal(); if (sysUser != null) { insuranceOperatLog.setOperatorName(sysUser.getLoginName()); insuranceOperatLog.setOperatorNo(sysUser.getUserNo()); } insuranceOperatRepository.save(insuranceOperatLog); super.postHandle(httpServletRequest,httpServletResponse,o,modelAndView); } catch (Exception ex) { log.error("调单操作异常日志保存异常{}", ex.getMessage()); } log.info("调单操作日志记录结束{}"); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { }(3) preHandle()方法 在业务处理器处理请求之前被调用 如果返回false 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链 如果返回true 执行下一个拦截器,直到所有的拦截器都执行完毕 再执行被拦截的Controller 然后进入拦截器链, 从最后一个拦截器往回执行所有的postHandle() 接着再从最后一个拦截器往回执行所有的afterCompletion() ;postHandle() 在业务处理器处理请求执行完成后,生成视图之前执行的动作 可在modelAndView中加入数据,比如当前时间 ;afterCompletion()方法 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 , 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion() 。
希望可以对大家有所帮助!