前面咱們作的小項目都是一個表的,業務代碼也相對簡單。如今咱們來作一個權限管理系統,體驗一下多表的業務邏輯,順便鞏固一下過濾器的知識。!html
如今我有一個管理商品、訂單的頁面。當用戶點擊某個超連接時,過濾器會檢測該用戶是否有權限!java
按照面向對象的思想,咱們至少應該有權限(Privilege)和用戶(User)實體。兩個實體足夠了嗎?細想一下,若是咱們有多個用戶,多個用戶也有多個權限,當要爲用戶受權的時候,這樣子就會很是麻煩!因此咱們應該引入角色(Role)這個實體!web
引入角色(Role)這個實體方便在哪呢??把權限賦給角色(好比:把刪除、修改的權限給管理員這個角色),管理員這個角色再賦給用戶,那麼該用戶就有了修改、刪除的權限了!sql
權限和角色是多對多的關係,角色和用戶也是多對多的關係!數據庫
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)
);
複製代碼
注意:user和role的關係表、role和privilege的關係都有role_id做爲外鍵,外鍵的名稱是不能同樣的!微信
/** * 權限的管理應該有如下的功能: * 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("查找權限失敗了!");
}
}
}
複製代碼
爲了測試方便,添加有參構造函數到Privilege對象中jsp
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());
}
}
複製代碼
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("添加權限失敗了!");
}
}
}
複製代碼
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());
}
}
}
複製代碼
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和Role表是多對多的關係,Role和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);
}
}
複製代碼
剛纔又思考了一下:
這就跟Hibernate的懶加載差很少。用到關聯關係的數據的時候才加載,沒有用到的時候就先不查詢數據庫。
ps:我不知道在這我理解得對不對,若是有錯的地方但願能指出!
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);
}
}
複製代碼
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);
}
}
複製代碼
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);
複製代碼
<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);
複製代碼
<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);
複製代碼
<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);
複製代碼
<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);
複製代碼
<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);
複製代碼
<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>
複製代碼
//獲得瀏覽器想要添加權利的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);
複製代碼
<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);
複製代碼
<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>
複製代碼
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集合。當用戶請求資源的時候,判斷該資源是否須要權限,若是須要權限,就判斷該用戶是否登錄了,若是登錄了,就判斷該用戶有沒有權限去訪問該資源!
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("登錄失敗了!!");
}
}
複製代碼
<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() {
}
複製代碼
①:用戶和權限的關係,因爲添加用戶的權限和修改用戶權限的不足【在權限不少的狀況下,這種狀況是很差處理的】,因此咱們引入了角色這個概念
②:用戶與角色,角色與權限都是多對多的關係
③:按照數據庫範式,咱們會建立5張實體表,其中兩張是表明着:用戶與角色、角色與權限的關係表。角色這個字段在外鍵中,不能同名!
④:不管是角色、用戶、權限都有這三個方法:獲得全部的權限(角色、用戶)、添加權限(角色、用戶)、權限的id獲得權限(角色、用戶)對象
⑤:根據id獲得具體的對象方法的意義:在web顯示層只能經過id來標識着這個對象,然而在後端經常使用的是對象,因而就有了這個方法。
⑥:多對多之間的關係,在程序中並非都要在其類上定義一個集合來記住對方。當顯示用戶時,須要顯示角色,可是顯示角色時,通常咱們是不須要顯示用戶的信息的。所以在角色上,並不須要維護一個集合來記住全部的用戶
⑦:獲得用戶的全部角色:傳入的參數一定有具體的用戶或角色,因此id必須是外界傳遞進來的。【獲得角色的全部權限是同理】
⑧:修改用戶的角色:咱們先把用戶的角色所有刪除了,再經過外界勾選的角色進行添加(這是一個折中的辦法)【修改角色的權限是同理】
⑨:在添加用戶角色的時候,要把用戶的id經過隱藏域傳遞進去給服務器端,否則是不知道要修改的是哪個用戶的角色的。【修改角色的權限是同理】
⑩:frameset和frame來實現前臺的分幀,target指定在哪裏顯示具體的數據
①①:在init()方法中用一個Map集合,以uri做爲key,以具體的權限做爲值來實現過濾
①②:若是uri不須要權限,直接放行。須要權限,那麼判斷該用戶是否登陸了。沒有登陸就讓用戶去登陸
①③:若是登陸了,就獲得用戶全部的權限,權限用一個Set集合裝載,遍歷Set集合,使用contains()方法就能夠查看出有沒有對應的權限了。
①④:使用contains()方法須要在權限類上重寫hashCode()和equals()方法的。由於咱們比較的是字符串。
若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章的同窗,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y