`
飞鱼德蒙
  • 浏览: 13027 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

【JavaWeb】权限管理系统

阅读更多

前言

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


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


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


效果:



显示用户

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


如果文章有错的地方欢迎指正,大家互相交流。正在学习Java和想学java的朋友如果需要交流和学习资料这里介绍一个Java技术交流群:318261748 有免费的学习资料提供给大家,群里都是学习Java的朋友,有什么问题都可以一起交流互相学习进步!

 

 

 

分享到:
评论

相关推荐

    javaweb权限管理系统

    【JavaWeb权限管理系统】是一个基于Java技术栈的后端应用,它主要利用Spring、SpringMVC和MyBatis这三个框架构建。系统的核心目标是提供一套完整的权限管理解决方案,确保不同用户在访问和操作Web应用程序时,能根据...

    javaweb权限管理系统(附数据库)

    JavaWeb权限管理系统是一种用于控制和管理用户访问系统资源的软件应用。这个系统包含了三个核心模块:用户管理、权限管理和角色管理。这些模块是构建任何安全应用程序的基础,它们确保只有授权的用户才能执行特定的...

    Javaweb权限管理系统 Jsp权限系统毕业设计 论文+源码+sql脚本 完整源码

    在这个“Javaweb权限管理系统”中,JSP作为视图层,负责展示数据和交互界面,而业务逻辑则由Java后端处理。这种分离模式有利于代码的维护和扩展。数据库选用MySQL,这是一种广泛使用的开源关系型数据库,具有良好的...

    javaweb+mybatis+struts权限管理系统

    在IT行业中,构建一个基于JavaWeb的权限管理系统是常见的需求,尤其当涉及到企业级应用时。这个系统通常采用MyBatis和Struts框架,以实现高效的数据持久化和灵活的控制逻辑。以下将详细阐述这些知识点: 1. **...

    java web权限管理系统

    Java Web权限管理系统是一种基于Web的应用程序,用于管理和控制不同用户对系统资源的访问权限。它通常采用分层架构,结合了多种技术来实现安全、高效的功能。在这个系统中,我们看到核心的技术栈包括Spring、...

    基于SSM框架的JavaWeb通用权限管理系统源码

    名称:基于SSM的JavaWeb权限管理系统 技术:Jsp 、SSM、Shiro 、Mvc、Jdbc、MySQL、DWZ富客户端框架 + Jquery + Ajax 环境:JDK:JDK1.6+ 、WEB:Tomcat6.0+ 、DB:MySQL5+ 、IDE: MyEclipse8.5+/Eclipse4.4+ 开发工具...

    图书管理系统,贪吃蛇,人力资源管理系统,客户管理系统,ERP仓库管理系统,机票管理系统,JavaWeb权限管理系统

    MD文档:详细介绍了每个项目的需求分析、系统设计、系统实现和测试等环节,让您能够全面了解项目的开发流程和关键技术。此外,还附带了详细的API文档,方便您查阅各个功能模块的接口和参数说明。 笔记资料:整理了...

    JavaWeb商品管理系统

    JavaWeb商品管理系统是一款基于JavaWeb技术开发的用于管理商品信息的系统。它提供了一套完整的功能,包括商品的增删改查、分类管理、库存管理、订单管理等。 该系统具备以下核心特性: 用户管理:通过注册和登录...

    JavaWeb名片管理系统

    《JavaWeb名片管理系统详解》 JavaWeb名片管理系统是一款利用Web技术实现的,旨在方便个人或组织存储、管理和分享名片信息的软件系统。该系统的核心架构是基于HTML、CSS、JavaScript等前端技术,与JSP、JavaBean、...

    javaweb 通用权限管理系统

    《JavaWeb通用权限管理系统详解》 在JavaWeb开发领域,权限管理是一个不可或缺的重要部分,它涉及到用户角色的划分、操作权限的控制以及安全性的保障。本文将深入探讨一个基于传统MVC设计模式的"通用权限管理系统...

    javaweb仓库管理系统.zip

    《JavaWeb仓库管理系统详解》 JavaWeb仓库管理系统是一款基于SSM框架(Spring、SpringMVC、MyBatis)开发的应用程序,适用于毕业设计和课程设计的学习参考。它旨在实现对仓库库存、进出货等业务流程的高效管理,...

    Javaweb学生管理系统

    《JavaWeb学生管理系统详解》 JavaWeb学生管理系统是一款基于JavaWeb技术实现的教育管理软件,主要用于高校或培训机构对学生信息的管理、查询、修改和统计。它整合了多种核心技术,包括Servlet、JSP、JDBC以及MVC...

    javaweb图书管理系统

    《JavaWeb图书管理系统详解》 JavaWeb图书管理系统是一款基于JAVA技术构建的Web应用程序,它集成了用户注册登录、管理员后台管理以及图书的管理查询等多种功能,为图书馆的日常运营提供了便利。本文将深入探讨该...

    javaweb 人员管理系统

    《JavaWeb人员管理系统详解》 JavaWeb人员管理系统是一款基于JavaWeb技术实现的,主要用于企业管理其员工信息的应用系统。系统提供用户和管理员两种角色的登录功能,具备查询、增加和删除等基本操作,使得企业的...

    JavaWeb后台管理系统

    JavaWeb后台管理系统是一种基于Java技术构建的企业级应用系统,主要用于管理网站内容、用户权限、数据处理等核心功能。在软件工程领域,这类系统是实现高效、安全和可扩展的网络服务的重要工具。以下是对JavaWeb后台...

    javaweb企业权限管理系统

    本项目“javaweb企业权限管理系统”就是基于SSM实现的,它为企业提供了完整的用户管理和权限控制功能,包括用户端和管理员端的登录、查询、修改、删除和添加等操作。 1. **Spring MVC**:作为Spring的一部分,...

    javaweb唱片管理系统

    JavaWeb唱片管理系统是一个基于Model-View-Controller(MVC)架构设计的初学者项目,它旨在帮助用户管理和销售唱片。这个系统可能包含了处理唱片信息、库存管理、订单处理以及用户交互等多个功能模块。 1. **...

    javaweb宿舍管理系统

    "javaweb宿舍管理系统"是一个基于JavaWeb技术开发的应用,主要设计用于高校或机构的宿舍管理。这个项目可以直接在MyEclipse集成开发环境中导入,并通过调整`jdbc.properties`文件来配置数据库连接,使得系统能够适应...

    基于javaWeb的酒店管理系统

    《基于JavaWeb的酒店管理系统详解》 在信息技术日益发达的今天,基于JavaWeb的酒店管理系统已经成为酒店行业提高运营效率、优化服务的重要工具。本系统以其完善的功能、灵活的架构和强大的数据库支持,为用户和管理...

Global site tag (gtag.js) - Google Analytics