- 提供显示权利页面的Servlet
//得到浏览器想要查看的角色id
Stringrole_id=request.getParameter("role_id");
RoleServiceroleService=newRoleService();
//根据id获取得到Role对象
Rolerole=roleService.findRole(role_id);
//得到当前角色所有的权利
List<Privilege>rolePrivilege=roleService.getRolePrivilege(role_id);
//得到系统所有的权利
PrivilegeServiceprivilegeService=newPrivilegeService();
List<Privilege>allPrivilege=privilegeService.getAllPrivileges();
request.setAttribute("role",role);
request.setAttribute("rolePrivilege",rolePrivilege);
request.setAttribute("allPrivilege",allPrivilege);
//跳转到显示页面
request.getRequestDispatcher("/WEB-INF/jsp/LookRolePrivilege.jsp").forward(request,response);
- 显示页面JSP
<tableborder="1px">
<tr>
<td>角色名称</td>
<td>${role.name}</td>
</tr>
<tr>
<td>当前角色拥有的权利</td>
<td>
<c:forEachitems="${rolePrivilege}"var="privi">
${privi.name}
</c:forEach>
</td>
</tr>
<tr>
<td>系统拥有的所有权利</td>
<td>
<formaction="${pageContext.request.contextPath}/AddRolePrivilegeController"method="post">
<%--让服务器知道要修改哪一个用户,就要把用户的id传递过去--%>
<inputtype="hidden"name="role_id"value="${role.id}">
<c:forEachitems="${allPrivilege}"var="privileges">
<inputtype="checkbox"name="privilege"value="${privileges.id}">${privileges.name}
</c:forEach>
<inputtype="submit"value="添加权利">
</form>
</td>
</tr>
</table>
- 效果:
- 处理表单数据并添加角色权利的Servlet
//得到浏览器想要添加权利的id
String[]ids=request.getParameterValues("privilege_id");
//获取角色id
Stringrole_id=request.getParameter("role_id");
try{
//得到想要添加权利的角色
RoleServiceroleService=newRoleService();
Rolerole=roleService.findRole(role_id);
//得到权利对象,用List对象装载起来
PrivilegeServiceprivilegeService=newPrivilegeService();
List<Privilege>privileges_list=newArrayList<>();
for(Stringid:ids){
Privilegeprivilege=privilegeService.findPrivilege(id);
privileges_list.add(privilege);
}
roleService.updateRolePrivilege(role,privileges_list);
request.setAttribute("message","为角色添加权利成功!");
}catch(Exceptione){
e.printStackTrace();
request.setAttribute("message","为角色添加权利失败!");
}
request.getRequestDispatcher("/message.jsp").forward(request,response);
权限模块
添加权限
- 提供添加权限页面的Servlet
//直接跳转到jsp页面
request.getRequestDispatcher("/WEB-INF/jsp/AddPrivilege.jsp").forward(request,response);
- 显示页面JSP
<formaction="${pageContext.request.contextPath}/AddPrivilegeController"method="post">
<tableborder="1px">
<tr>
<td>权限名字</td>
<td><inputtype="text"name="name"></td>
</tr>
<tr>
<td>权限描述</td>
<td><textareaname="description"cols="30"rows="10"></textarea></td>
</tr>
<tr>
<td><inputtype="submit"value="添加权限"></td>
<td><inputtype="reset"value="重置"></td>
</tr>
</table>
</form>
- 效果:
- 处理表单数据,并添加权限的Servlet
//得到浏览器带过来的数据
Stringname=request.getParameter("name");
Stringdescription=request.getParameter("description");
//封装数据到Privilege对象
Privilegeprivilege=newPrivilege();
privilege.setId(WebUtils.makeId().substring(3,10));
privilege.setName(name);
privilege.setDescription(name);
try{
PrivilegeServiceprivilegeService=newPrivilegeService();
privilegeService.addPrivilege(privilege);
request.setAttribute("message","添加权限成功!");
}catch(Exceptione){
e.printStackTrace();
request.setAttribute("message","添加权限失败!");
}
request.getRequestDispatcher("/message.jsp").forward(request,response);
查看所有权限
- 提供页面的Servlet
//得到所有的权限
PrivilegeServiceprivilegeService=newPrivilegeService();
List<Privilege>list=privilegeService.getAllPrivileges();
request.setAttribute("list",list);
request.getRequestDispatcher("/WEB-INF/jsp/LookPrivileges.jsp").forward(request,response);
- 显示权限页面的JSP
<c:iftest="${empty(list)}">
您还没添加任何的权限
</c:if>
<c:iftest="${!empty(list)}">
<tableborder="1px">
<tr>
<td>权限名称</td>
<td>描述</td>
<td>操作</td>
</tr>
<c:forEachitems="${list}"var="privilege">
<tr>
<td>${privilege.name}</td>
<td>${privilege.description}</td>
<td>
<ahref="#">删除权限</a>
<ahref="#">修改权限</a>
</td>
</tr>
</c:forEach>
</table>
</c:if>
- 效果:
用分帧把功能拼接
- head页面
<bodystyle="text-align: center">
<h1>XX管理系统</h1>
</body>
- left页面
<body>
<ahref="${pageContext.request.contextPath}/LookUserUI"target="body">用户管理</a><br><br><br><br>
<ahref="${pageContext.request.contextPath}/LookRolesUI"target="body">角色管理</a><br><br><br><br>
<ahref="${pageContext.request.contextPath}/LookPrivileges"target="body">权限管理</a><br><br><br><br>
</body>
- body页面是空白的!
- index页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<framesetrows="25%,*">
<framesrc="head.jsp"name="head">
<framesetcols="15%,*">
<framesrc="left.jsp"name="left">
<framesrc="body.jsp"name="body">
</frameset>
</frameset>
</html>
- 效果:
过滤器
过滤器主要的工作就是:点击超链接时,过滤器会检测该点击者是否有权限进入页面进行操作(CURD)。
这里我们是这样子做的:uri作为key,权限作为value,构成一个Map集合。当用户请求资源的时候,判断该资源是否需要权限,如果需要权限,就判断该用户是否登陆了,如果登陆了,就判断该用户有没有权限去访问该资源!
- 在UserDao和UserService中需要添加login方法:
补充的代码
publicUserlogin(Stringusername,Stringpassword){
try{
QueryRunnerqueryRunner=newQueryRunner(JdbcUtils.getDataSource());
Stringsql="SELECT * FROM user WHERE username=? AND password=?";
Useruser=(User)queryRunner.query(sql,newBeanHandler(User.class),newObject[]{username,password});
returnuser;
}catch(Exceptione){
e.printStackTrace();
thrownewRuntimeException("登陆失败了!!");
}
}
- 登陆界面的JSP
<formaction="${pageContext.request.contextPath}/LoginController"method="post">
用户名:<inputtype="text"name="username"><br>
密码:<inputtype="password"name="password"><br>
<inputtype="submit"value="登陆"><br>
</form>
- 处理登陆的Servlet
//获取表单数据
Stringusername=request.getParameter("username");
Stringpassword=request.getParameter("password");
UserServiceuserService=newUserService();
Useruser=userService.login(username,password);
if(user!=null){
request.setAttribute("message","恭喜你,登陆成功了!");
request.getSession().setAttribute("user",user);
}else{
request.setAttribute("message","用户名或密码出错了!!");
}
request.getRequestDispatcher("/message.jsp").forward(request,response);
Filter代码
- 完整代码:
privateMap<String,Privilege>map=newHashMap<>();
publicvoidinit(FilterConfigconfig)throwsServletException{
map.put("/addServlet",newPrivilege("增加"));
map.put("/deleteServlet",newPrivilege("删除"));
map.put("/updateServlet",newPrivilege("修改"));
map.put("/findServlet",newPrivilege("查账单"));
}
publicvoiddoFilter(ServletRequestreq,ServletResponseresp,FilterChainchain)throwsServletException,IOException{
HttpServletRequestrequest=(HttpServletRequest)req;
HttpServletResponseresponse=(HttpServletResponse)resp;
//得到用户请求的资源地址
Stringuri=request.getRequestURI();
System.out.println(uri);
//通过key获取值,看看能不能获取得到值【为空,就是不需要权限了】
if(map.get(uri)==null){
chain.doFilter(request,response);
System.out.println("放行了");
return;
}
//如果不为空,就是需要权限。需要权限的话,就判断请求者是否登陆了!
if(request.getSession().getAttribute("user")==null){
request.setAttribute("message","您登陆了再来操作把!");
request.getRequestDispatcher("/message.jsp").forward(request,response);
return;
}
//如果登陆了,就查一下用户的权限是否和访问资源的权限匹配
Useruser=(User)request.getSession().getAttribute("user");
UserServiceuserService=newUserService();
RoleServiceroleService=newRoleService();
//得到用户所有的角色
List<Role>roles=userService.getUserRole(user.getId());
//通过角色,得到所有的权限【一个角色有多个权限,如果用户角色很多,那么权限也就很多了】
//此时,我们又要用集合来装载每一个角色的权限了!
Setprivileges=newHashSet();
for(Rolerole:roles){
List<Privilege>list=roleService.getRolePrivilege(role.getId());
privileges.addAll(list);
}
//得到的Set集合就是用户所有的权限了!!!!!
//集合的contains方法比较的是默认对象,而我们想要比较的是字符串名称,所以我们要在Privilege对象中重写equals和hashCode方法!
if(!privileges.contains(map.get(uri))){
request.setAttribute("message","你没有权限哟");
request.getRequestDispatcher("/message.jsp").forward(request,response);
return;
}
//到这里,就是有权限了
chain.doFilter(request,response);
}
publicvoiddestroy(){
}
测试
总结要点
①:用户和权限的关系,由于添加用户的权限和修改用户权限的不足【在权限很多的情况下,这种情况是不好处理的】,所以我们引入了角色这个概念
②:用户与角色,角色与权限都是多对多的关系
③:按照数据库范式,我们会创建5张实体表,其中两张是代表着:用户与角色、角色与权限的关系表。角色这个字段在外键中,不能同名!
④:无论是角色、用户、权限都有这三个方法:得到所有的权限(角色、用户)、添加权限(角色、用户)、权限的id得到权限(角色、用户)对象
⑤:根据id得到具体的对象方法的意义:在web显示层只能通过id来标识着这个对象,然而在后端常常使用的是对象,于是就有了这个方法。
⑥:多对多之间的关系,在程序中并不是都要在其类上定义一个集合来记住对方。当显示用户时,需要显示角色,但是显示角色时,一般我们是不需要显示用户的信息的。因此在角色上,并不需要维护一个集合来记住所有的用户
⑦:得到用户的所有角色:传入的参数必定有具体的用户或角色,所以id必须是外界传递进来的。【得到角色的所有权限是同理】
⑧:修改用户的角色:我们先把用户的角色全部删除了,再通过外界勾选的角色进行添加(这是一个折中的办法)【修改角色的权限是同理】
⑨:在添加用户角色的时候,要把用户的id通过隐藏域传递进去给服务器端,不然是不知道要修改的是哪一个用户的角色的。【修改角色的权限是同理】
⑩:frameset和frame来实现前台的分帧,target指定在哪里显示具体的数据
①①:在init()方法中用一个Map集合,以uri作为key,以具体的权限作为值来实现过滤
①②:如果uri不需要权限,直接放行。需要权限,那么判断该用户是否登录了。没有登录就让用户去登录
①③:如果登录了,就得到用户所有的权限,权限用一个Set集合装载,遍历Set集合,使用contains()方法就可以查看出有没有对应的权限了。
①④:使用contains()方法需要在权限类上重写hashCode()和equals()方法的。因为我们比较的是字符串。