接上一篇,现在需要让不同角色的用户登录之后,index.jsp页面左侧菜单栏看到不同的菜单,此时猫哥想到两种方式:
方式1,将菜单和角色-菜单的对应信息保存到数据库中。
方式2,将菜单和角色-菜单的对应信息直接保存到内存中。
因为培训班作业管理系统较为简单,所以直接采用方式2:
task3-8
,添加一个Constant类用于保存常量的信息如下:
package util;
import java.util.HashMap;
public class Constant {//保存常量信息
//roleMenu用于保存角色及对应的菜单信息
public static HashMap<String,String[][]> roleMenu=new HashMap<String,String[][]>();
//使用static代码块对roleMenu进行初始化
static{
//注意,二位数组中的每一组表示一个菜单的信息,又通过map建立了角色名和菜单直接的对应关系
roleMenu.put("校长", new String[][]{
{"人员管理","userManage","userManage.jsp"},//每组三个元素分别对应菜单名,菜单对应的Servlet参数,菜单对应的jsp
{"信息查询","viewInfo","viewInfo.jsp"}
});
roleMenu.put("教师", new String[][]{});
roleMenu.put("学生", new String[][]{});
}
}
task3-9
,所以,用户登录时,应同时将该用户对应的菜单信息保存到Session中。故修改LoginServlet如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {//处理post请求
//设置输入输出格式、编码
response.setContentType("text/html");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//获取用户在网页输入的用户名和密码
String userName=request.getParameter("userName");
String userPassword=request.getParameter("userPassword");
//数据库操作
LoginCommand lc=new LoginCommand();
User user=null;
try {
user=lc.checkLogin(userName, userPassword);
if(user==null)
throw new MyException(new Date(),"用户名或者密码错误","用户名或者密码错误");
//根据user.getUserRole();用户角色显示不同内容
request.getSession().setAttribute("loginUser", user);//记录登录用户信息
String[][] loginRoleMenu=Constant.roleMenu.get(user.getUserRole().getRoleName());//根据用户角色名找到对应菜单信息
request.getSession().setAttribute("loginRoleMenu", loginRoleMenu);//记录登录用户的菜单信息
request.getRequestDispatcher("/index.jsp").forward(request,response);//跳转到index.jsp
} catch (MyException e) {
//跳转到错误提示页面,并提示用户错误信息
request.setAttribute("errorInfo", e.getInfo());//设置错误信息
request.getRequestDispatcher("/error.jsp").forward(request,response);//跳转到error.jsp
}
}
task3-10
,然后就是修改index.jsp页面左侧菜单栏的菜单列表了,将如下代码:
<div id="left">
<ul>
<li><a href="/HomeworkSystem/RouteServlet?type=userManage">人员管理</a></li>
<li><a href="/HomeworkSystem/RouteServlet?type=viewInfo">信息查询</a></li>
</ul>
</div><!-- left部分是菜单栏 -->
修改为:
<div id="left">
<ul>
<c:forEach items="${loginRoleMenu}" var="menu">
<li>
<a href="/HomeworkSystem/RouteServlet?type=${menu[1]}">${menu[0]}</a>
</li>
</c:forEach>
</ul>
</div><!-- left部分是菜单栏 -->
PS:猫哥以前还真没用c:forEach处理过二维数组,突然有点懵圈,百度了一下更加懵圈,幸亏自己又想起来了,真是年龄大了。
OK,重新部署后运行,果然是index.jsp显示没有问题,接下来继续处理菜单栏点击之后的处理。
task3-11
,修改RouteServlet类的doPost方法如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {//处理post请求
//设置输入输出格式、编码
response.setContentType("text/html");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//获取用户在网页输入的用户名和密码
String type=request.getParameter("type");
//将type设置为根据Session中的loginRoleMenu匹配
String[][] loginRoleMenu=(String[][])request.getSession().getAttribute("loginRoleMenu");
//寻找对应Servlet路径的jsp文件名
for(String[] menu:loginRoleMenu){
if(menu[1].equals(type)){
type=menu[2];
}
}
request.setAttribute("type",type);
request.getRequestDispatcher("/index.jsp").forward(request,response);//跳转到index.jsp
}
重新部署、运行,达到了想要的效果,同时将菜单的相关信息都放置在了Constants类中,之后无论是想把菜单信息放到数据库还是配置文件,都好解决,通过Constants转换下就行呗。
PS:猫哥好像无意中还实现了一个功能,因为RouteServlet中要去loginRoleMenu查找对应的jsp名,而loginRoleMenu又跟登录用户角色相关。那么是不是可以说,一个角色想访问另一个角色的菜单对应的jsp页面,是会报错的。这个错误信息可以直接跳转到error.jsp页面,并显示无访问权限就可以了。
纯属PS,下篇验证下。