【JavaWeb】权限管理系统
2018-02-26 15:49
302 查看
前言
前面我们做的小项目都是一个表的,业务代码也相对简单。现在我们来做一个权限管理系统,体验一下多表的业务逻辑,顺便巩固一下过滤器的知识。!目的
现在我有一个管理商品、订单的页面。当用户点击某个超链接时,过滤器会检测该用户是否有权限!需求分析
按照面向对象的思想,我们至少应该有权限(Privilege)和用户(User)实体。两个实体足够了吗?细想一下,如果我们有多个用户,多个用户也有多个权限,当要为用户授权的时候,这样子就会非常麻烦!所以我们应该引入角色(Role)这个实体!引入角色(Role)这个实体方便在哪呢??把权限赋给角色(比如:把删除、修改的权限给管理员这个角色),管理员这个角色再赋给用户,那么该用户就有了修改、删除的权限了!
权限和角色是多对多的关系,角色和用户也是多对多的关系!
开发实体
用户实体
public class User { private String id; private String username; private String password; //记住角色 private Set<Role> roles = new HashSet<>(); //各种getter和setter..... }
角色实体
public class Role { private String id; private String name; private String description; //记住所有的用户 private Set<User> users = new HashSet<>(); //记住所有的权限 private Set<Privilege> privileges = new HashSet<>(); //各种getter和setter..... }
权限实体
public class Privilege { private String id; private String name; private String description; //记住所有的角色 private Set<Role> roles = new HashSet<>(); //各种getter和setter..... }
改良
用户和角色、角色和权限都是多对多的关系,这是毋庸置疑的!我们也按照面向对象的方法来设计,用集合来记住另一方的数据!但是呢,我们想想:
在权限的Dao中,在查看权限的时候,有必要列出相对应的角色吗??
在角色的Dao中,在查看角色的时候,有必要列出相对应的用户吗??
答案是没有的,一般我们都不会显示出来。所以,权限的实体没必要使用Set集合来记住角色,角色实体没必要使用Set集合来记住用户!
改良后的权限实体
public class Privilege { private String id; private String name; private String description; //各种setter和getter方法 }
改良后的角色实体
public class Role { private String id; private String name; private String description; //记住所有的权限 private Set<Privilege> privileges = new HashSet<>(); //各种setter和getter方法 }
在数据库中建表
user表
CREATE TABLE user ( id VARCHAR(20) PRIMARY KEY, username VARCHAR(20) NOT NULL, password VARCHAR(20) NOT NULL );
role表
CREATE TABLE role ( id VARCHAR(20) PRIMARY KEY, name VARCHAR(20) NOT NULL, description VARCHAR(255) );
privilege表
CREATE TABLE privilege ( id VARCHAR(20) PRIMARY KEY, name VARCHAR(20) NOT NULL, description VARCHAR(255) );
user和role的关系表
CREATE TABLE user_role ( user_id VARCHAR(20), role_id VARCHAR(20), PRIMARY KEY (user_id, role_id), CONSTRAINT user_id_FK FOREIGN KEY (user_id) REFERENCES user (id), CONSTRAINT role_id_FK FOREIGN KEY (role_id) REFERENCES role (id) );
role和privilege的关系表
CREATE TABLE role_privilege ( role_id VARCHAR(20), privilege_id VARCHAR(20), PRIMARY KEY (role_id, privilege_id), CONSTRAINT role_id_FK1 FOREIGN KEY (role_id) REFERENCES role (id), CONSTRAINT privilege_id_FK FOREIGN KEY (privilege_id) REFERENCES privilege (id) );
注意:user和role的关系表、role和privilege的关系都有role_id作为外键,外键的名称是不能一样的!
开发DAO
PrivilegeDao
/** * 权限的管理应该有以下的功能: * 1.添加权限 * 2.查看所有权限 * 3.查找某个权限 * * */ public class PrivilegeDao { /*添加权限*/ public void addPrivilege(Privilege privilege) { try { QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "INSERT INTO privilege (id, name, description) VALUE (?, ?, ?)"; queryRunner.update(sql, new Object[]{privilege.getId(), privilege.getName(), privilege.getDescription()}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("添加权限失败了!"); } } /*查找权限*/ public Privilege findPrivilege(String id) { try { QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "SELECT *FROM privilege WHERE id = ?"; Privilege privilege = (Privilege) queryRunner.query(sql, new BeanHandler(Privilege.class), new Object[]{id}); return privilege; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("查找权限失败了!"); } } /*获取所有的权限*/ public List<Privilege> getAllPrivileges() { try { QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "SELECT * FROM privilege "; List<Privilege> privileges = (List<Privilege>) queryRunner.query(sql, new BeanListHandler(Privilege.class)); return privileges; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("查找权限失败了!"); } } }
测试PrivilegeDao的功能
为了测试方便,添加有参构造函数到Privilege对象中public class PrivilegeDaoTest { PrivilegeDao privilegeDao = new PrivilegeDao(); @Test public void add() { Privilege privilege = new Privilege("2", "修改", "修改功能"); privilegeDao.addPrivilege(privilege); } @Test public void getAll() { List<Privilege> list = privilegeDao.getAllPrivileges(); for (Privilege privilege : list) { System.out.println(privilege.getId()); } } @Test public void find() { String id = "2"; Privilege privilege = privilegeDao.findPrivilege(id); System.out.println(privilege.getName()); } }
UserDao
public class UserDao { public void addUser(User user) { try { QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "INSERT INTO user (id,username,password) VALUES(?,?,?)"; queryRunner.update(sql, new Object[]{user.getId(), user.getUsername(), user.getPassword()}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("添加权限失败了!"); } } public User find(String id) { try { QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "SELECT * FROM user WHERE id=?"; User user = (User) queryRunner.query(sql, new BeanHandler(User.class), new Object[]{id}); return user; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("添加权限失败了!"); } } public List<User> getAll() { try { QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "SELECT * FORM user"; List<User> users = (List<User>) queryRunner.query(sql, new BeanListHandler(User.class)); return users; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("添加权限失败了!"); } } }
測試UserDao
public class UserDaoTest { UserDao userDao = new UserDao(); @Test public void add() { User user = new User(); user.setId("2"); user.setUsername("qqq"); user.setPassword("123"); userDao.addUser(user); } @Test public void find() { String id = "1"; User user = userDao.find(id); System.out.println(user.getUsername()); } @Test public void findALL() { List<User> userList = userDao.getAll(); for (User user : userList) { System.out.println(user.getUsername()); } } }
RoleDao
public void add(Role role){ try{ QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "insert into role(id,name,description) values(?,?,?)"; Object params[] = {role.getId(),role.getName(),role.getDescription()}; runner.update(sql, params); }catch (Exception e) { throw new RuntimeException(e); } } public Role find(String id){ try{ QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from role where id=?"; return (Role) runner.query(sql, id, new BeanHandler(Role.class)); }catch (Exception e) { throw new RuntimeException(e); } } //得到所有角色 public List<Role> getAll(){ try{ QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from role"; return (List<Role>) runner.query(sql, new BeanListHandler(Role.class)); }catch (Exception e) { throw new RuntimeException(e); } }
测试RoleDao
RoleDao roleDao = new RoleDao(); @Test public void add() { Role role = new Role(); role.setId("1"); role.setName("manager"); role.setDescription("this is a manager"); roleDao.add(role); } @Test public void find( ) { String id = "1"; Role role = roleDao.find(id); System.out.println(role.getName()); } @Test public void getAdd() { List<Role> roleList = roleDao.getAll(); for (Role role : roleList) { System.out.println(role.getName()); } }
补充
上面的仅仅是单表的Dao功能,User和Role表是多对多的关系,Role和Privilege表也是多对多的关系。前面已经分析了
在User对象中,需要一个Set集合来记住Role的关系。【显示用户的时候,应该把所有角色显示出来】
在Role对象中,需要一个Set集合来记住Privilege的关系【显示角色的时候,应该把所有权限显示很出来】。
所以应该在UserDao有获取某用户所有的角色的方法:
/*得到用戶的所有角色*/ public List<Role> getRoles(String user_id) { try { QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); //根據用戶id查詢所有角色,重點就在角色上,所以要有role表。然后查詢user_role表,就可以鎖定用戶id對應的角色了! String sql = "SELECT r.* FROM role r, user_role ur WHERE ur.user_id = ? AND r.id = ur.role_id "; List<Role> roles = (List<Role>) queryRunner.query(sql, new BeanListHandler(Role.class), new Object[]{user_id}); return roles; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("得到用戶所有的角色失败了!"); } }
在RoleDao有获取所有权限的方法:
//得到某角色的所有權限【權限表、權限和角色關系表】 public List<Privilege> getPrivileges(String role_id) { try{ QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "SELECT p.* FROM privilege p, role_privilege rp WHERE rp.role_id = ? AND p.id = rp.role_id"; List<Privilege> privileges = (List<Privilege>) runner.query(sql, new BeanListHandler(Privilege.class), new Object[]{role_id}); return privileges; }catch (Exception e) { throw new RuntimeException(e); } }
我们既然能获取得到用户所有的角色了,获取得到角色所有的权限了。那自然我们就应该有修改用户的角色功能,修改角色的权限的功能啦!
我们先来分析一下它怎么写:要修改用户所拥有的角色,应该知道修改用户是哪一个,所以需要用户的id或者User对象!修改的角色是什么,需要Role对象或者装载Role对象的集合!
在UserDao有修改某用户角色的方法,我们是想把所有的角色都删除了,再添加新的角色
//更新用戶的角色 public void updateRole(User user, List<Role> roles) { try { QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); //先把用戶原來的所有角色刪掉了 String delete = "DELETE FROM user_role WHERE user_id = ?"; queryRunner.update(delete, user.getId()); String add = "INSERT INTO user_role (user_id,role_id) VALUES(?,?)"; for (Role role : roles) { queryRunner.update(add, new Object[]{user.getId(), role.getId()}); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("添加权限失败了!"); } }
在RoleDao有修改角色权限的方法,和上面是类似的。
//为某个角色授权 public void addPrivilege2Role(Role role, List<Privilege> privileges) { try{ QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource()); //先刪除該角色的所有權限 String delete = "DELETE FROM role_privilege WHERE role_id = ?"; runner.update(delete, new Object[]{role.getId()}); //賦予角色新的權限 String sql = "INSERT INTO role_privilege (role_id, privilege_id) VALUES (?, ?)"; for (Privilege privilege : privileges) { runner.update(sql, new Object[]{role.getId(), privilege.getId()}); } }catch (Exception e) { throw new RuntimeException(e); } }
更新
刚才又思考了一下:- 其实我们并不需要在User类用使用集合来维护Role,在Role中使用集合来维护Privilege。在原本的做法我们已经看到了,我们完全是不需要这两个变量也能完成效果的。
- 那么,现在问题就来了。什么时候我们才需要在实体中使用变量来维护多的一方的关系呢???我觉得是这样的:当我们在查询一方数据的时候,另一方的数据也同时需要展示。那么此时我们就应该使用集合来维护多的一方数据了。
- 基于上面一个例子,就比如:订单与订单项。当我们查看订单的时候,同时一定会把所有的订单项都列举出来。
- 再比如:当我们查看购物车的时候,就需要把所有的购物项都列举出来。
- 而我们使用展示用户的时候,并不需要第一时间就把角色列举出来,而是通过超链接来查看用户下的角色,基于这种情况,我觉得我们是不用使用集合变量来维护多的一方的数据的。
这就跟Hibernate的懒加载差不多。用到关联关系的数据的时候才加载,没有用到的时候就先不查询数据库。
ps:我不知道在这我理解得对不对,如果有错的地方希望能指出!
开发BusinessService
UserService
public class UserService { UserDao userDao = new UserDao(); //添加用户 public void addUser(User user) { userDao.addUser(user); } //根据id查找用户 public User findUser(String id) { return userDao.find(id); } //得到所有的用户 public List<User> getAllUser() { return userDao.getAll(); } //获取用户所有的角色 public List<Role> getUserRole(String user_id) { return userDao.getRoles(user_id); } //修改用户的角色 public void updateUserRole(User user, List<Role> roles) { userDao.updateRole(user, roles); } }
RoleService
public class RoleService { RoleDao roleDao = new RoleDao(); //添加角色 public void addRole(Role role) { roleDao.add(role); } //根据id查找角色 public Role findRole(String id) { return roleDao.find(id); } //获取所有的角色 public List<Role> getAllRole() { return roleDao.getAll(); } //获取角色所有的权限 public List<Privilege> getRolePrivilege(String role_id) { return roleDao.getPrivileges(role_id); } //修改角色的权限 public void updateRolePrivilege(Role role, List<Privilege> privileges) { roleDao.addPrivilege2Role(role, privileges); } }
PrivilegeService
public class PrivilegeService { PrivilegeDao privilegeDao = new PrivilegeDao(); //添加权限 public void addPrivilege(Privilege privilege) { privilegeDao.addPrivilege(privilege); } //根据id获得权限 public Privilege findPrivilege(String id) { return privilegeDao.findPrivilege(id); } //获取所有的权限 public List<Privilege> getAllPrivileges() { return privilegeDao.getAllPrivileges(); } }
开发Web
用户模块
添加用户
提供页面界面的Servlet//直接跳转到显示添加用户的界面 request.getRequestDispatcher("/WEB-INF/jsp/addUser.jsp").forward(request, response);
显示页面的JSP
<form action="AddUserController" method="post"> <table> <tr> <td>用户名:</td> <td><input type="text" name="username"></td> </tr> <tr> <td>密码:</td> <td><input type="password" name="password"></td> </tr> <tr> <td><input type="submit" value="添加用户"></td> <td><input type="reset" value="重置"></td> </tr> </table> </form>
处理表单数据的Servlet
//得到客户端传递进来的参数 String username = request.getParameter("username"); String password = request.getParameter("password"); User user = new User(); user.setId(WebUtils.makeId()); user.setUsername(username); user.setPassword(password); try { UserService userService = new UserService(); userService.addUser(user); request.setAttribute("message","添加用户成功!"); } catch (Exception e) { request.setAttribute("message", "添加用户失败!"); throw new RuntimeException("在Controller添加客户失败"); } request.getRequestDispatcher("/message.jsp").forward(request,response); }
效果:
显示用户
提供页面界面的ServletUserService userService = new UserService(); List<User> list = userService.getAllUser(); request.setAttribute("list", list); //跳转到显示页面 request.getRequestDispatcher("/WEB-INF/jsp/LookUser.jsp").forward(request, response);
显示页面JSP
<c:if test="${empty(list)}"> 对不起,暂时没有任何客户 </c:if> <c:if test="${!empty(list)}"> <table border="1px"> <tr> <td>用户名</td> <td>密码</td> </tr> <c:forEach items="${list}" var="user"> <tr> <td>${user.username}</td> <td>${user.password}</td> </tr> </c:forEach> </table> </c:if>
效果:
为用户添加角色
在显示用户的基础上,应该添加为用户授权角色的超链接。<table border="1px"> <tr> <td>用户名</td> <td>密码</td> <td>操作</td> </tr> <c:forEach items="${list}" var="user"> <tr> <td>${user.username}</td> <td>${user.password}</td> <td> <a href="${pageContext.request.contextPath}/LookUserRole?user_id=${user.id}"> 为用户授权角色 </a> <a href="#">修改用户</a> <a href="#">删除用户</a> </td> </tr> </c:forEach> </table>
效果:
处理显示授权页面的Servlet
//得到客户端传递过来的user_id String user_id = request.getParameter("user_id"); //获取该用户所有的角色 UserService userService = new UserService(); List<Role> userRoles = userService.getUserRole(user_id); //得到全部的角色 RoleService roleService = new RoleService(); List<Role> allRoles = roleService.getAllRole(); //为用户授权的JSP页面也应该显示用户的信息,所以把User对象也传递过去给JSP页面 User user = userService.findUser(user_id); request.setAttribute("user", user); request.setAttribute("userRoles", userRoles); request.setAttribute("allRoles", allRoles); //跳转到显示页面 request.getRequestDispatcher("/WEB-INF/jsp/LookUserRole.jsp").forward(request, response);
授权页面JSP
<table border="1px"> <tr> <td>当前用户名称</td> <td>${user.username}</td> </tr> <tr> <td>当前用户所拥有的角色</td> <td> <c:forEach items="${userRoles}" var="userRole"> ${userRole.name} </c:forEach> </td> </tr> <tr> <td>当前系统所拥有的角色</td> <td> <form method="post" action="${pageContext.request.contextPath}/AddUserRole"> <%--要为用户添加角色,需要知道是哪一个用户,通过hidden传递过去用户的id--%> <input type="hidden" name="user_id" value="${user.id}"> <c:forEach items="${allRoles}" var="roles"> <input type="checkbox" name="role_id" value="${roles.id}">${roles.name} </c:forEach> <input type="submit" value="添加角色!"> </form> </td> </tr> </table>
效果:
处理表单数据并为用户添加角色的Servlet
//得到传递进来的role_id String[] ids = request.getParameterValues("role_id"); try { //得到想要修改哪个用户的id String user_id = request.getParameter("user_id"); //通过id获取得到User对象 UserService userService = new UserService(); User user = userService.findUser(user_id); //通过id获取得到Role对象,再把对象用List集合装载起来 RoleService roleService = new RoleService(); List<Role> list = new ArrayList<>(); for (String id : ids) { Role role = roleService.findRole(id); list.add(role); } //更新用户所拥有的角色 userService.updateUserRole(user, list); request.setAttribute("message","添加角色成功!"); } catch (Exception e) { e.printStackTrace(); request.setAttribute("message","添加角色失败!"); } request.getRequestDispatcher("/message.jsp").forward(request,response);
效果:
角色模块
添加角色
提供添加角色页面的Servlet//直接跳转到jsp页面即可 request.getRequestDispatcher("WEB-INF/jsp/AddRole.jsp").forward(request, response);
显示页面JSP
<form action="${pageContext.request.contextPath}/AddRoleController" method="post"> <table border="1px"> <tr> <td>角色名称</td> <td><input type="text" name="name"></td> </tr> <tr> <td>详细描述</td> <td><textarea name="description" cols="30" rows="10"></textarea></td> </tr> <tr> <td> <input type="submit" value="添加角色"> </td> </tr> </table> </form>
处理表单数据并添加角色的Servlet
//得到客户端带过来的数据 String name = request.getParameter("name"); String description = request.getParameter("description"); try { //创建对象并封装数据 Role role = new Role(); role.setId(WebUtils.makeId()); role.setName(name); role.setDescription(description); //调用Service方法,完成功能 RoleService roleService = new RoleService(); roleService.addRole(role); request.setAttribute("message","添加角色成功!"); } catch (Exception e) { request.setAttribute("message","添加角色失败!"); e.printStackTrace(); } request.getRequestDispatcher("/message.jsp").forward(request, response);
效果:
查看所有的角色
提供页面的Servlet//得到所有的角色 RoleService roleService = new RoleService(); List<Role> list = roleService.getAllRole(); request.setAttribute("list", list); request.getRequestDispatcher("/WEB-INF/jsp/LookRoles.jsp").forward(request, response);
显示页面JSP
<c:if test="${empty(list)}"> 您还没有任何角色,请添加! </c:if> <c:if test="${!empty(list)}"> <table border="1px"> <tr> <td>角色名称</td> <td>描述</td> </tr> <c:forEach items="${list}" var="role"> <tr> <td>${role.name}</td> <td>${role.description}</td> </tr> </c:forEach> </table> </c:if>
效果
为角色授权
与上面是类似的,我们要在查看角色的时候,添加授权的功能!<c:forEach items="${list}" var="role"> <tr> <td>${role.name}</td> <td>${role.description}</td> <td> <a href="${pageContext.request.contextPath}/LookRolePrivilege?role_id=${role.id}"> 为角色授权 </a> <a href="#">删除角色</a> <a href="#">修改角色</a> </td> </tr> </c:forEach>
效果:
提供显示权利页面的Servlet
//得到浏览器想要查看的角色id String role_id = request.getParameter("role_id"); RoleService roleService = new RoleService(); //根据id获取得到Role对象 Role role = roleService.findRole(role_id); //得到当前角色所有的权利 List<Privilege> rolePrivilege = roleService.getRolePrivilege(role_id); //得到系统所有的权利 PrivilegeService privilegeService = new PrivilegeService(); 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
<table border="1px"> <tr> <td>角色名称</td> <td>${role.name}</td> </tr> <tr> <td>当前角色拥有的权利</td> <td> <c:forEach items="${rolePrivilege}" var="privi"> ${privi.name} </c:forEach> </td> </tr> <tr> <td>系统拥有的所有权利</td> <td> <form action="${pageContext.request.contextPath}/AddRolePrivilegeController" method="post"> <%--让服务器知道要修改哪一个用户,就要把用户的id传递过去--%> <input type="hidden" name="role_id" value="${role.id}"> <c:forEach items="${allPrivilege}" var="privileges"> <input type="checkbox" name="privilege" value="${privileges.id}">${privileges.name} </c:forEach> <input type="submit" value="添加权利"> </form> </td> </tr> </table>
效果:
处理表单数据并添加角色权利的Servlet
//得到浏览器想要添加权利的id String[] ids = request.getParameterValues("privilege_id"); //获取角色id String role_id = request.getParameter("role_id"); try { //得到想要添加权利的角色 RoleService roleService = new RoleService(); Role role = roleService.findRole(role_id); //得到权利对象,用List对象装载起来 PrivilegeService privilegeService = new PrivilegeService(); List<Privilege> privileges_list = new ArrayList<>(); for (String id : ids) { Privilege privilege = privilegeService.findPrivilege(id); privileges_list.add(privilege); } roleService.updateRolePrivilege(role, privileges_list); request.setAttribute("message","为角色添加权利成功!"); } catch (Exception e) { 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
<form action="${pageContext.request.contextPath}/AddPrivilegeController" method="post"> <table border="1px"> <tr> <td>权限名字</td> <td><input type="text" name="name"></td> </tr> <tr> <td>权限描述</td> <td><textarea name="description" cols="30" rows="10"></textarea></td> </tr> <tr> <td><input type="submit" value="添加权限"></td> <td><input type="reset" value="重置"></td> </tr> </table> </form>
效果:
处理表单数据,并添加权限的Servlet
//得到浏览器带过来的数据 String name = request.getParameter("name"); String description = request.getParameter("description"); //封装数据到Privilege对象 Privilege privilege = new Privilege(); privilege.setId(WebUtils.makeId().substring(3,10)); privilege.setName(name); privilege.setDescription(name); try { PrivilegeService privilegeService = new PrivilegeService(); privilegeService.addPrivilege(privilege); request.setAttribute("message","添加权限成功!"); } catch (Exception e) { e.printStackTrace(); request.setAttribute("message", "添加权限失败!"); } request.getRequestDispatcher("/message.jsp").forward(request, response);
效果:
查看所有权限
提供页面的Servlet//得到所有的权限 PrivilegeService privilegeService = new PrivilegeService(); List<Privilege> list = privilegeService.getAllPrivileges(); request.setAttribute("list", list); request.getRequestDispatcher("/WEB-INF/jsp/LookPrivileges.jsp").forward(request, response);
显示权限页面的JSP
<c:if test="${empty(list)}"> 您还没添加任何的权限 </c:if> <c:if test="${!empty(list)}"> <table border="1px"> <tr> <td>权限名称</td> <td>描述</td> <td>操作</td> </tr> <c:forEach items="${list}" var="privilege"> <tr> <td>${privilege.name}</td> <td>${privilege.description}</td> <td> <a href="#">删除权限</a> <a href="#">修改权限</a> </td> </tr> </c:forEach> </table> </c:if>
效果:
用分帧把功能拼接
head页面<body style="text-align: center"> <h1>XX管理系统</h1> </body>
left页面
<body> <a href="${pageContext.request.contextPath}/LookUserUI" target="body">用户管理</a><br><br><br><br> <a href="${pageContext.request.contextPath}/LookRolesUI" target="body">角色管理</a><br><br><br><br> <a href="${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> <frameset rows="25%,*"> <frame src="head.jsp" name="head"> <frameset cols="15%,*"> <frame src="left.jsp" name="left"> <frame src="body.jsp" name="body"> </frameset> </frameset> </html>
效果:
过滤器
过滤器主要的工作就是:点击超链接时,过滤器会检测该点击者是否有权限进入页面进行操作(CURD)。这里我们是这样子做的:uri作为key,权限作为value,构成一个Map集合。当用户请求资源的时候,判断该资源是否需要权限,如果需要权限,就判断该用户是否登陆了,如果登陆了,就判断该用户有没有权限去访问该资源!
在UserDao和UserService中需要添加login方法:
补充的代码
public User login(String username, String password) { try { QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "SELECT * FROM user WHERE username=? AND password=?"; User user = (User) queryRunner.query(sql, new BeanHandler(User.class), new Object[]{username, password}); return user; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("登陆失败了!!"); } }
登陆界面的JSP
<form action="${pageContext.request.contextPath}/LoginController" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit" value="登陆"><br> </form>
处理登陆的Servlet
//获取表单数据 String username = request.getParameter("username"); String password = request.getParameter("password"); UserService userService = new UserService(); User user = 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代码
完整代码:private Map<String, Privilege> map = new HashMap<>(); public void init(FilterConfig config) throws ServletException { map.put("/addServlet", new Privilege("增加")); map.put("/deleteServlet", new Privilege("删除")); map.put("/updateServlet", new Privilege("修改")); map.put("/findServlet", new Privilege("查账单")); } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //得到用户请求的资源地址 String uri = 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; } //如果登陆了,就查一下用户的权限是否和访问资源的权限匹配 User user = (User) request.getSession().getAttribute("user"); UserService userService = new UserService(); RoleService roleService = new RoleService(); //得到用户所有的角色 List<Role> roles = userService.getUserRole(user.getId()); //通过角色,得到所有的权限【一个角色有多个权限,如果用户角色很多,那么权限也就很多了】 //此时,我们又要用集合来装载每一个角色的权限了! Set privileges = new HashSet(); for (Role role : 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); } public void destroy() { }
测试
总结要点
①:用户和权限的关系,由于添加用户的权限和修改用户权限的不足【在权限很多的情况下,这种情况是不好处理的】,所以我们引入了角色这个概念②:用户与角色,角色与权限都是多对多的关系
③:按照数据库范式,我们会创建5张实体表,其中两张是代表着:用户与角色、角色与权限的关系表。角色这个字段在外键中,不能同名!
④:无论是角色、用户、权限都有这三个方法:得到所有的权限(角色、用户)、添加权限(角色、用户)、权限的id得到权限(角色、用户)对象
⑤:根据id得到具体的对象方法的意义:在web显示层只能通过id来标识着这个对象,然而在后端常常使用的是对象,于是就有了这个方法。
⑥:多对多之间的关系,在程序中并不是都要在其类上定义一个集合来记住对方。当显示用户时,需要显示角色,但是显示角色时,一般我们是不需要显示用户的信息的。因此在角色上,并不需要维护一个集合来记住所有的用户
⑦:得到用户的所有角色:传入的参数必定有具体的用户或角色,所以id必须是外界传递进来的。【得到角色的所有权限是同理】
⑧:修改用户的角色:我们先把用户的角色全部删除了,再通过外界勾选的角色进行添加(这是一个折中的办法)【修改角色的权限是同理】
⑨:在添加用户角色的时候,要把用户的id通过隐藏域传递进去给服务器端,不然是不知道要修改的是哪一个用户的角色的。【修改角色的权限是同理】
⑩:frameset和frame来实现前台的分帧,target指定在哪里显示具体的数据
①①:在init()方法中用一个Map集合,以uri作为key,以具体的权限作为值来实现过滤
①②:如果uri不需要权限,直接放行。需要权限,那么判断该用户是否登录了。没有登录就让用户去登录
①③:如果登录了,就得到用户所有的权限,权限用一个Set集合装载,遍历Set集合,使用contains()方法就可以查看出有没有对应的权限了。
①④:使用contains()方法需要在权限类上重写hashCode()和equals()方法的。因为我们比较的是字符串。
如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章的同学,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y
相关文章推荐
- javaweb+SSH实现简单的权限管理系统
- 【JavaWeb】权限管理系统
- 【JavaWeb】权限管理系统
- 用户角色权限管理系统-----java web 脚手架搭建(一)
- javaweb+SSH实现简单的权限管理系统
- java web 权限管理系统设计与实现
- javaweb 项目的系统权限管理,怎么设计?shiro简单了解
- JAVA_WEB项目(结合Servlet+jsp+ckEditor编辑器+jquery easyui技术)实现新闻发布管理系统第一篇:前期环境准备
- 如何在自己的信息管理系统里集成第三方权限控制组件 - 设计一个漂亮的WEB界面
- web工作流管理系统开发之六 表单权限与流程的权限控制
- Java_Web之宠物管理系统
- java web 项目 图书管理系统的设计与实现
- Java_Web之俱乐部会员信息管理系统
- Java权限管理系统源代码下载
- JAVA_WEB项目(结合Servlet+jsp+ckEditor编辑器+jquery easyui技术)实现新闻发布管理系统第二篇:登陆和注销功能实现
- 基于web信息管理系统的权限设计分析和总结
- 通用权限管理系统多语言开发接口 - java,php 调用接口程序,多业务子系统集成
- javaweb系统基本权限模块
- JAVA_WEB项目(结合Servlet+jsp+ckEditor编辑器+jquery easyui技术)实现新闻发布管理系统第三篇:新闻发布,新闻修改,新闻删除功能的实现