您的位置:首页 > 编程语言 > Java开发

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐