【JavaWeb】权限管理系统

简介: 前言前面我们做的小项目都是一个表的,业务代码也相对简单。现在我们来做一个权限管理系统,体验一下多表的业务逻辑,顺便巩固一下过滤器的知识。!目的现在我有一个管理商品、订单的页面。当用户点击某个超链接时,过滤器会检测该用户是否有权限!需求分析按照面向对象的思想,我们至少应该有权限(Privilege)和用户(User)实体。

前言

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


目的

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

这里写图片描述


需求分析

按照面向对象的思想,我们至少应该有权限(Privilege)和用户(User)实体。两个实体足够了吗?细想一下,如果我们有多个用户,多个用户也有多个权限,当要为用户授权的时候,这样子就会非常麻烦!所以我们应该引入角色(Role)这个实体!

引入角色(Role)这个实体方便在哪呢??把权限赋给角色(比如:把删除、修改的权限给管理员这个角色),管理员这个角色再赋给用户,那么该用户就有了修改、删除的权限了!

权限和角色是多对多的关系,角色和用户也是多对多的关系!


开发实体

用户实体


public class User {

    private String id;
    private String username;
    private String password;

    //记住角色
    private Set roles = new HashSet<>();

    //各种getter和setter.....


}

角色实体


public class Role {
    private String id;
    private String name;
    private String description;

    //记住所有的用户
    private Set users = new HashSet<>();

    //记住所有的权限
    private Set privileges = new HashSet<>();

    //各种getter和setter.....
}

权限实体


public class Privilege {

    private String id;
    private String name;
    private String description;

    //记住所有的角色
    private Set 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 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 getAllPrivileges() {

        try {

            QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
            String sql = "SELECT * FROM privilege ";

            List privileges = (List) 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 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 getAll() {
        try {

            QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());

            String sql = "SELECT * FORM user";
            List users = (List) 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 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 getAll(){
        try{

            QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
            String sql = "select * from role";
            return (List) 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 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 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 roles = (List) queryRunner.query(sql, new BeanListHandler(Role.class), new Object[]{user_id});

            return roles;
        } catch (Exception e) {

            e.printStackTrace();
            throw new RuntimeException("得到用戶所有的角色失败了!");
        }

    }

在RoleDao有获取所有权限的方法




    //得到某角色的所有權限【權限表、權限和角色關系表】
    public List 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 privileges = (List) 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 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 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 getAllUser() {
            return userDao.getAll();
        }
    
        //获取用户所有的角色
        public List getUserRole(String user_id) {
            return userDao.getRoles(user_id);
        }
    
        //修改用户的角色
        public void updateUserRole(User user, List 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 getAllRole() {
            return roleDao.getAll();
        }
    
        //获取角色所有的权限
        public List getRolePrivilege(String role_id) {
            return roleDao.getPrivileges(role_id);
        }
    
        //修改角色的权限
        public void updateRolePrivilege(Role role, List 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 getAllPrivileges() {
            return privilegeDao.getAllPrivileges();
        }
    }

开发Web

用户模块

添加用户

  • 提供页面界面的Servlet
        //直接跳转到显示添加用户的界面
        request.getRequestDispatcher("/WEB-INF/jsp/addUser.jsp").forward(request, response);
  • 显示页面的JSP

    
用户名:
密码:
  • 处理表单数据的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 list = userService.getAllUser();
        request.setAttribute("list", list);

        //跳转到显示页面
        request.getRequestDispatcher("/WEB-INF/jsp/LookUser.jsp").forward(request, response);

  • 显示页面JSP



    对不起,暂时没有任何客户



    
用户名 密码
${user.username} ${user.password}
  • 效果:

这里写图片描述


为用户添加角色

在显示用户的基础上,应该添加为用户授权角色的超链接。



    
用户名 密码 操作
${user.username} ${user.password} 为用户授权角色 修改用户 删除用户
  • 效果:

这里写图片描述

  • 处理显示授权页面的Servlet


        //得到客户端传递过来的user_id
        String user_id = request.getParameter("user_id");

        //获取该用户所有的角色
        UserService userService = new UserService();
        List userRoles = userService.getUserRole(user_id);

        //得到全部的角色
        RoleService roleService = new RoleService();
        List 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



当前用户名称 ${user.username}
当前用户所拥有的角色 ${userRole.name}
当前系统所拥有的角色 ${roles.name}
  • 效果:

这里写图片描述

  • 处理表单数据并为用户添加角色的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 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


    
角色名称
详细描述
  • 处理表单数据并添加角色的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 list = roleService.getAllRole(); request.setAttribute("list", list); request.getRequestDispatcher("/WEB-INF/jsp/LookRoles.jsp").forward(request, response); 
  • 显示页面JSP
 您还没有任何角色,请添加! 
角色名称 描述
${role.name} ${role.description}
  • 效果

这里写图片描述


为角色授权

与上面是类似的,我们要在查看角色的时候,添加授权的功能!

 
${role.name} ${role.description} 为角色授权 删除角色 修改角色
  • 效果:

这里写图片描述


  • 提供显示权利页面的Servlet
 //得到浏览器想要查看的角色id String role_id = request.getParameter("role_id"); RoleService roleService = new RoleService(); //根据id获取得到Role对象 Role role = roleService.findRole(role_id); //得到当前角色所有的权利 List rolePrivilege = roleService.getRolePrivilege(role_id); //得到系统所有的权利 PrivilegeService privilegeService = new PrivilegeService(); List 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
 
角色名称 ${role.name}
当前角色拥有的权利 ${privi.name}
系统拥有的所有权利 ${privileges.name}
  • 效果:

这里写图片描述


  • 处理表单数据并添加角色权利的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 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
 
权限名字
权限描述
  • 效果:

这里写图片描述


  • 处理表单数据,并添加权限的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 list = privilegeService.getAllPrivileges(); request.setAttribute("list", list); request.getRequestDispatcher("/WEB-INF/jsp/LookPrivileges.jsp").forward(request, response); 
  • 显示权限页面的JSP
 您还没添加任何的权限 
权限名称 描述 操作
${privilege.name} ${privilege.description} 删除权限 修改权限
  • 效果:

这里写图片描述


用分帧把功能拼接

  • head页面
 

XX管理系统

  • left页面
 
用户管理



角色管理



权限管理



  • body页面是空白的!

  • index页面:

 
  • 效果:

这里写图片描述


过滤器

过滤器主要的工作就是:点击超链接时,过滤器会检测该点击者是否有权限进入页面进行操作(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
 
用户名:
密码:

  • 处理登陆的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 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 roles = userService.getUserRole(user.getId()); //通过角色,得到所有的权限【一个角色有多个权限,如果用户角色很多,那么权限也就很多了】 //此时,我们又要用集合来装载每一个角色的权限了! Set privileges = new HashSet(); for (Role role : roles) { List 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

目录
相关文章
|
29天前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
|
20天前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
1月前
|
运维 自然语言处理 供应链
Java云HIS医院管理系统源码 病案管理、医保业务、门诊、住院、电子病历编辑器
通过门诊的申请,或者直接住院登记,通过”护士工作站“分配患者,完成后,进入医生患者列表,医生对应开具”长期医嘱“和”临时医嘱“,并在电子病历中,记录病情。病人出院时,停止长期医嘱,开具出院医嘱。进入出院审核,审核医嘱与住院通过后,病人结清缴费,完成出院。
86 3
|
1月前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
37 1
|
1月前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
2月前
|
移动开发 前端开发 JavaScript
java家政系统成品源码的关键特点和技术应用
家政系统成品源码是已开发完成的家政服务管理软件,支持用户注册、登录、管理个人资料,家政人员信息管理,服务项目分类,订单与预约管理,支付集成,评价与反馈,地图定位等功能。适用于各种规模的家政服务公司,采用uniapp、SpringBoot、MySQL等技术栈,确保高效管理和优质用户体验。
|
2月前
|
XML JSON 监控
告别简陋:Java日志系统的最佳实践
【10月更文挑战第19天】 在Java开发中,`System.out.println()` 是最基本的输出方法,但它在实际项目中往往被认为是不专业和不足够的。本文将探讨为什么在现代Java应用中应该避免使用 `System.out.println()`,并介绍几种更先进的日志解决方案。
61 1
|
2月前
|
Java 关系型数据库 API
介绍一款Java开发的企业接口管理系统和开放平台
YesApi接口管理平台Java版,基于Spring Boot、Vue.js等技术,提供API接口的快速研发、管理、开放及收费等功能,支持多数据库、Docker部署,适用于企业级PaaS和SaaS平台的二次开发与搭建。
|
2月前
|
前端开发 Java 数据库连接
基于Java的校车管理系统(下)
基于Java的校车管理系统(下)
25 0
|
2月前
|
存储 前端开发 Java
基于Java的校车管理系统
基于Java的校车管理系统(上)
26 0
下一篇
DataWorks