[JavaWeb] Система управления правами

Java Java EE

предисловие

Все небольшие проекты, которые мы делали ранее, представляют собой таблицы, а бизнес-код относительно прост. Теперь давайте создадим систему управления разрешениями, испытаем бизнес-логику нескольких таблиц и, кстати, закрепим знания о фильтрах. !


Цель

Теперь у меня есть страница управления продуктами, заказами. Когда пользователь нажимает на гиперссылку, фильтр определяет, есть ли у пользователя разрешение!

这里写图片描述


анализ спроса

Согласно объектно-ориентированному мышлению, мыПо крайней мере должны быть сущности Privilege и User. Достаточно ли двух объектов? Подумайте об этом, если у нас есть несколько пользователей, а несколько пользователей имеют несколько разрешений, когда мы хотим авторизовать пользователей, это будет очень хлопотно! Значит надо ввести роль (Роль) этой сущности!

В чем удобство введения роли сущности? ?Назначьте разрешения ролям (например: назначьте права на удаление и изменение роли администратора), а затем назначьте роль администратора пользователю, тогда у пользователя есть разрешение на изменение и удаление!

Разрешения и роли - это много отношений отношений, ролей и пользователей - много!


Субъекты развития

Объект пользователя


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.....

}

улучшать

**Пользователи и роли, роли и разрешения находятся во взаимосвязи «многие ко многим», это точно! ** Мы также проектируем в соответствии с объектно-ориентированным подходом,Используйте коллекции, чтобы запомнить данные другой стороны!

Но давайте подумаем:

  • В Дао разрешений нужно ли перечислять соответствующие роли при просмотре разрешений? ?
  • В Дао роли при просмотре роли обязательно указывать соответствующего пользователя? ?

Ответ - нет, обычно мы этого не показываем.Следовательно, сущности разрешений не обязательно использовать коллекцию 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方法


}



создать таблицу в базе данных

пользовательская таблица



	CREATE TABLE user (
	  id       VARCHAR(20) PRIMARY KEY,
	  username VARCHAR(20) NOT NULL,
	  password VARCHAR(20) NOT NULL
	
	
	);



таблица ролей



	CREATE TABLE role (
	  id          VARCHAR(20) PRIMARY KEY,
	  name        VARCHAR(20) NOT NULL,
	  description VARCHAR(255)
	
	);


таблица привилегий

	CREATE TABLE privilege (
	
	  id          VARCHAR(20) PRIMARY KEY,
	  name        VARCHAR(20) NOT NULL,
	  description VARCHAR(255)
	
	
	);

Таблица отношений между пользователем и ролью


	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)
	);

Таблица отношений между ролью и привилегией


	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)
	
	);


Примечание. Таблица взаимосвязей между пользователем и ролью, а также связь между ролью и привилегией имеют role_id в качестве внешнего ключа, и имена внешних ключей не могут совпадать!


Разработать ДАО

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 = 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 коллекция 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);
        }
    }


Теперь, когда мы можем получить все роли пользователя, мы можем получить все разрешения роли. Тогда, естественно, у нас должна быть функция изменения роли пользователя и изменения разрешений роли!

Давайте сначала проанализируем, как это написано:Чтобы изменить роль, принадлежащую пользователю, вы должны знать, какого пользователя изменить, поэтому вам нужен идентификатор пользователя или объект пользователя! Что такое модифицированная роль, требуется объект 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, а использовать коллекцию для поддержания Привилегии в Роли. В первоначальной практике мы видели, что нам вообще не нужны эти две переменные для достижения эффекта.
  • Ну а теперь вопрос. Когда нам нужно использовать переменные в сущностях для поддержания отношений «многие ко многим»? ? ? Я думаю, что это так: когда мы запрашиваем данные одной стороны, данные другой стороны такжев то же времяНужно показать. Затем мы должны использовать коллекции для хранения большего количества данных.
  • На основе приведенного выше примера, например: Заказы и позиции. Когда мы смотрим на заказ, мы обязательно перечисляем все позиции одновременно.
  • Еще один пример: когда мы просматриваем корзину, нам нужно перечислить все товары покупок.
  • И когда мы используем дисплей пользователя,не нужно в первый разПеречислите роли, но просмотрите роли под пользователем через гиперссылки.Исходя из этой ситуации, я думаю, что нам не нужно использовать установленные переменные для ведения данных более стороны.

Это похоже на ленивую загрузку Hibernate. Данные отношения ассоциации загружаются, когда они используются, и база данных не запрашивается, когда они не используются.

PS: Я не знаю, понимаю ли я это прямо здесь, если что-то не так, я надеюсь, что это может быть указано!


Разработка БизнесСервис

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();
	    }
	}

разработать веб

Пользовательский модуль

Добавить пользователя

  • Сервлет, обеспечивающий интерфейс страницы
        //直接跳转到显示添加用户的界面
        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>


  • Форма сервлета обработка данных

        //得到客户端传递进来的参数
        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);
        
    }

  • Эффект:

这里写图片描述


показать пользователей

  • Сервлет, обеспечивающий интерфейс страницы

        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>
  • Эффект:

这里写图片描述

  • Обработать сервлет, отображающий страницу авторизации


        //得到客户端传递过来的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>

  • Эффект:

这里写图片描述

  • Сервлет, который обрабатывает данные формы и добавляет роли пользователям


        //得到传递进来的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);

  • Эффект:

这里写图片描述


ролевой модуль

Добавить роль

  • Сервлет, предоставляющий страницу добавления роли

        //直接跳转到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>

  • Сервлет, который обрабатывает данные формы и добавляет роли


        //得到客户端带过来的数据
        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);
  • Эффект:

这里写图片描述


Посмотреть все роли

  • Сервлет, обслуживающий страницу


        //得到所有的角色
        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>
  • Эффект:

这里写图片描述


  • Сервлет, обеспечивающий отображение страницы прав доступа

        //得到浏览器想要查看的角色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);
  • Эффект:

这里写图片描述


модуль разрешений

Добавить разрешение

  • Сервлет, предоставляющий страницу добавления разрешений

        //直接跳转到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>

  • Эффект:

这里写图片描述


  • Сервлет, который обрабатывает данные формы и добавляет разрешения

        //得到浏览器带过来的数据
        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);


  • Эффект:

这里写图片描述


Посмотреть все разрешения

  • Сервлет, обслуживающий страницу



        //得到所有的权限
        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>

  • Эффект:

这里写图片描述


Функции сшивания с обрамлением

  • главная страница

	<body style="text-align: center">
	
	<h1>XX管理系统</h1>
	</body>


  • левая страница

	
	<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>
  • Основная страница пуста!

  • индексная страница:



	<%@ 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 используется в качестве ключа, а разрешение используется в качестве значения, формируя коллекцию карт. Когда пользователь запрашивает ресурс, оценивается, нуждается ли ресурс в разрешении.Если требуется разрешение, оценивается, вошел ли пользователь в систему.Если он вошел в систему, оценивается, есть ли у пользователя разрешение на доступ к ресурсу!

  • Метод входа необходимо добавить в UserDao и UserService:

дополнительный код



    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>

  • Сервлет, который обрабатывает вход в систему


        //获取表单数据
        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);

Код фильтра

  • Полный код:

    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() {
    }


контрольная работа

这里写图片描述


Итоговые пункты

①: Отношения между пользователями и разрешениями из-за недостаточности добавления разрешений пользователей и изменения разрешений пользователей [в случае многих разрешений эту ситуацию непросто решить], поэтому мы ввели концепцию ролей.

②: Между пользователями и ролями, ролями и разрешениями существует связь «многие ко многим».

③: В соответствии с парадигмой базы данных мы создадим пять таблиц сущностей, две из которых являются таблицами отношений, представляющими: пользователей и роли, роли и разрешения. Поле роли находится во внешнем ключе и не может иметь такое же имя!

④: Существует три метода для ролей, пользователей и разрешений: получить все разрешения (роли, пользователи), добавить разрешения (роли, пользователи) и получить разрешения (роли, пользователи) объектов по идентификатору разрешений.

⑤: Значение метода конкретного объекта в соответствии с идентификатором: на уровне веб-отображения объект может быть идентифицирован только по идентификатору, но объект часто используется в бэкэнде, поэтому существует этот метод.

⑥: Отношения между многими ко многим, в программе нет необходимости определять набор в своем классе, чтобы помнить друг друга. При отображении пользователя нам нужно отображать роль, но при отображении роли нам обычно не нужно отображать информацию о пользователе. Таким образом, для ролей нет необходимости поддерживать набор, чтобы помнить всех пользователей.

⑦: Получить все роли пользователя: входящие параметры должны иметь конкретных пользователей или роли, поэтому идентификатор должен быть передан из внешнего мира. [Получить все разрешения роли одинаковы]

⑧: Изменить роль пользователя: Сначала мы удаляем все роли пользователя, а затем добавляем их через роли, выбранные внешним миром (это метод компромисса) [Разрешение на изменение роли такое же]

⑨: При добавлении роли пользователя передайте идентификатор пользователя на сервер через скрытое поле, иначе вы не будете знать, какую роль пользователя изменить. [Разрешение на изменение роли такое же]

⑩: набор фреймов и фрейм для достижения внешнего фрейма, цель указывает, где отображать конкретные данные

①①: Используйте коллекцию карт в методе init(), используйте uri в качестве ключа и используйте конкретное разрешение в качестве значения для фильтрации.

①②: Если URI не нуждается в разрешении, отпустите его напрямую. Если требуется разрешение, то определите, вошел ли пользователь войти в систему. Пусть пользователь войдет в систему без входа в систему

13: Если вы входите в систему, вы получаете все разрешения пользователя, разрешение загружено с помощью установленного собрания, пересекайте набор набор, вы можете использовать метод CONET (), чтобы увидеть, есть ли какие-либо соответствующие разрешения.

①④: Чтобы использовать метод contains(), вам нужно переписать методы hashCode() и equals() в классе разрешений. Потому что мы сравниваем строки.


Если в статье есть какие-либо ошибки, пожалуйста, поправьте меня, и мы сможем общаться друг с другом. Студенты, которые привыкли читать технические статьи в WeChat, и студенты, которые хотят получить больше ресурсов по Java, могутОбратите внимание на публичный аккаунт WeChat: Java3y