从这一节起开始讲拦截器、日志、异常等的处理。
为了防止用户在未登录的情况下访问系统,需要对每个请求进行登录校验,为了防止未授权用户访问系统的操作,也需要对每个请求进行权限校验,这里用到了SpringMVC的拦截器,通过该拦截器可以灵活配置要校验哪些请求。
拦截器配置
<!--设置拦截器,处理登录及权限控制-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/index.htm"/>
<mvc:mapping path="/sys/*/*"/>
<bean class="com.critc.plat.core.interceptor.CheckLoginInterceptor"></bean>
</mvc:interceptor>
<!-- -->
<mvc:interceptor>
<mvc:mapping path="/sys/*/*"/>
<bean class="com.critc.plat.core.interceptor.AuthorityInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
这里配置了两个拦截器,第一个是校验登录的,拦截/index.htm
和/sys/*/*
映射的,第二个是权限校验拦截器,拦截/sys/*/*
。
后面系统开发系统功能,都可以把具体映射加到这地方,相对来讲配置还是比较灵活的。
CheckLoginInterceptor.java
public class CheckLoginInterceptor implements HandlerInterceptor {
/**
* 操作前先判断是否登录,未登录跳转到登录界面
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
UserSession userSession = SessionUtil.getUserSession(request);
if (userSession == null) {
boolean isAjaxRequest = StringUtil.checkAjaxRequest(request);
if (isAjaxRequest) {
WebUtil.out(response, JsonUtil.createOperaStr(false, "连接超时,请重新登录!"));
} else {
String str = "<script>top.location.href='" + request.getContextPath() + "/'</script>";
WebUtil.out(response, str);
}
return false;
} else {
return true;
}
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
这段代码比较容易,定义一个拦截器,实现HandlerInterceptor
接口,只需要处理preHandle
该方法即可。再判断session是否为null的时候,判断当前请求是不是ajax请求,如果是,返回json,如果是普通请求,跳转至登录页面。
AuthorityInterceptor.java
/**
* 校验权限,如果无权限,提示权限不足
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
UserSession userSession = SessionUtil.getUserSession(request);
//校验权限
String path = request.getServletPath();
path = path.substring(1, path.length());
String operaMethod = path.substring(path.lastIndexOf("/"));
operaMethod = operaMethod.substring(1, operaMethod.length());
String parameters = StringUtil.getOperaParams(request);
//记操作日志
logOperation(path, parameters, userSession);
//目前只校验add/update/delete/save/import开头的方法,其余不校验
boolean checked = sysRoleService.checkAuthority(userSession.getRoleId(), path);
if (checked) {
if (checkUrl(operaMethod)) {
//记录数据库日志
sysLogService.addLog(userSession.getUserId(), path, parameters, userSession.getUserIp());
}
return true;
} else {
boolean isAjaxRequest = StringUtil.checkAjaxRequest(request);
if (isAjaxRequest) {
WebUtil.out(response, JsonUtil.createOperaStr(false, "权限不足"));
} else {
String location = pubConfig.getDynamicServer() + "/error.htm?msg=" + StringUtil.encodeUrl("权限不足");
String str = "<script>location.href='" + location + "';</script>";
WebUtil.out(response, str);
}
return false;
}
}
/**
* 记录文本日志
*
* @param path
* @param parameters
* @param us
*/
public void logOperation(String path, String parameters, UserSession us) {
String log = "";
log = "[OPERALOG]" + "-[" + us.getUserIp() + "]" + "-[" + DateUtil.getSystemTime() + "]-" + "[" + us.getUsername() + "]-" + "[INFO]-" + path + "-" + parameters;
logger.info(log);
}
校验权限的原理就是先取到请求url,然后根据当前用户的roleId来获取具备的权限,判断该url是否在权限的HashMap中,如果不在,则提示权限不足。
如下图所示:
校验权限后同时记录日志,这里日志包括两类,所有请求都记录文本日志,通过logback记录,包括ip、时间、用户id、url、参数等,所有操作日志,包括add、update、delete、save、import
开头的方法都记录数据库。所以在制定url的约定时,如果该请求涉及数据库修改,一定要以上述方法开头。
文本日志如下所示:
文本日志.png
网友评论