背景
前端效果类似于下图:
父子级菜单分别对应不同的操作权限、访问路径等。
数据库建三张表:
1.operate 页面菜单配置表
id即为权限id,url为菜单对应页面地址,type控制菜单是否显示。
2.action 请求url配置表
action为对应操作请求的url,operate即为对应操作权限,log控制是否打印日志。
3.account用户表
保存用户信息、操作权限等。
核心代码:
1.创建一个Interceptor 类 ,实现HandlerInterceptor
接口,完成检查是否有权限的核心代码
public class GmtoolsInterceptor implements HandlerInterceptor {
@Resource
GmDataDao gmDataDao;
public void doLog(String account, String operate, String content, String ip) {
HashMap<String, Object> param = new HashMap<String, Object>();
param.put("account", account);
param.put("operate", operate);
param.put("content", content);
param.put("ip", ip);
gmDataDao.insertLog(param);
}
public String getIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown"))
ip = request.getHeader("Proxy-Client-IP");
if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown"))
ip = request.getHeader("WL-Proxy-Client-IP");
if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown"))
ip = request.getRemoteAddr();
if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown"))
ip = "unknown";
return ip;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
List<String> operate;
String account;
HashMap<String, Object> action;
String path = request.getServletPath();
action = gmDataDao.queryAction(path);
if (action == null)
return false;
if ((int) action.get("operate") == 0)
return true;
account = (String) session.getAttribute("account");
messageDigest.update(request.getHeader("user-agent").getBytes());
//1.检查是否登录
if (account == null || !session.getAttribute("ua").equals(new String(messageDigest.digest()))) {
response.getWriter().write("{ \"result\" : -3 }");
return false;
}
if ((int) action.get("operate") == 1)
return true;
//2.检查是否有权限
operate = Arrays.asList(gmDataDao.queryOperate(account).split(","));
if (!operate.contains(action.get("operate").toString())) {
response.getWriter().write("{ \"result\" : -2 }");
return false;
}
Map<String, String[]> map = request.getParameterMap();
Map<String, Object> param = new HashMap<String, Object>();
for (String key : map.keySet())
param.put(key, Arrays.asList(map.get(key)));
//打印日志
if ((int) action.get("log") == 1)
doLog(account, (String) action.get("name"), param.toString(), getIp(request));
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception e) throws Exception {
}
}
HandlerInterceptor 接口定义了三个方法,执行顺序如下:
preHandler -> Controller -> postHandler -> model渲染-> afterCompletion
2.新建WebAppConfig
类继承 WebMvcConfigurerAdapter
@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {
@Bean
GmtoolsInterceptor gmtoolsInterceptor() {
return new GmtoolsInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(gmtoolsInterceptor()).excludePathPatterns("/");
super.addInterceptors(registry);
}
}
其中addPathPatterns 和 excludePathPatterns 方法,进行拦截器配置。addPathPatterns 配置需要拦截的请求路径,excludePathPatterns配置不需要拦截的请求路径。