zoukankan      html  css  js  c++  java
  • 权限管理系统

    前言

    前面我们做的小项目都是一个表的,业务代码也相对简单。现在我们来做一个权限管理系统,体验一下多表的业务逻辑,顺便巩固一下过滤器的知识!


    目的

    现在我有一个管理商品、订单的页面。当用户点击某个超链接时,过滤器会检测该用户是否有权限!

    这里写图片描述


    需求分析

    按照面向对象的思想,我们至少应该有权限(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);
            }
        }
    

    开发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);
    
        }
    
    • 效果:

    这里写图片描述


    显示用户

    • 提供页面界面的Servlet
    
            UserService 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()方法的。因为我们比较的是字符串。

    如果您觉得这篇文章帮助到了您,可以给作者一点鼓励



  • 相关阅读:
    kNN算法python实现和简单数字识别的方法
    python3.4学习笔记(二十) python strip()函数 去空格 函数的用法
    SolrCloud分布式集群部署步骤
    hbases索引技术:Lily HBase Indexer介绍
    HBase1.0以上版本的API改变
    Hbase1.0 客户端api
    java.io.IOException: Could not locate executable nullinwinutils.exe in the Hadoop binaries
    Resharp最新破解方法
    Cloudera Manager 5和CDH5离线安装
    Apache Thrift
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7203030.html
Copyright © 2011-2022 走看看