許可權管理系統 - 1 連線:使用者&角色&模組
許可權管理系統
作用:對不同使用者的許可權進行限定,管理對應的模組
涉及模組:使用者User、角色Role、模組Module(或許可權Permission)
目錄- 許可權管理系統
0 基本步驟
-
1 三個模組的基本CRUD
-
使用者User + 角色Role + 模組Module
-
domian 實體類User 、Role 、Module
-
dao 介面
-
xxxDao.xml
-
service 介面+實現類
-
BaseServlet service靜態成員變數 * 3
-
UserServlet、RoleServlet、ModuleServlet
-
-
-
2 動態載入授權資料(樹形頁面元件)
-
/WEB-INF/pages/子系統/role/list.jsp
- 授權按鈕 傳遞id
- /system/role?operation=author&id=${o.id}
- 授權按鈕 傳遞id
-
servlet
- RoleServlet新增author方法
- 將樹形的動態資料以json方式放入域
- RoleServlet新增author方法
-
author.jsp
-
定義頁面樹形元件
-
使用靜態資料確認樹形結構功能是否完備
-
-
ModuleService + ModuleServiceImpl
- findAuthorDataByRoleId方法
-
ModuleDao
- findAuthorDataByRoleId方法
-
ModuleDao.xml
-
findAuthorDataByRoleId對應SQL語句
-
按照頁面資料結構(JSON)拼寫SQL
-
-
-
3 繫結角色與模組關係
-
WEB-INF\pages\子系統\role\author.jsp
- 實現許可權分配:選中複選框,授予對應許可權
-
RoleServlet
- 新增方法updateRoleModule
-
RoleService + RoleServiceImpl
- updateRoleModule方法
-
RoleDao
-
deleteRoleModule方法
-
saveRoleModule方法
-
-
RoleDao.xml
-
deleteRoleModule
-
saveRoleModule
-
-
-
4 繫結使用者與角色關係 - 資料回顯
-
\WEB-INF\pages\system\user\list.jsp
- 角色 按鈕 href
- 子系統/user?operation=userRoleList&id="+id
- 角色 按鈕 href
-
UserServlet - userRoleList方法
- 將資料傳遞到 角色 頁面
-
RoleService + RoleServiceImpl - findAllRoleByUserId方法
- 根據使用者id查詢角色列表
-
RoleDao - findAllRoleByUserId方法
-
RoleDao.xml - 新增對應的查詢
-
/WEB-INF/pages/system/user/role.jsp
- 新增checked
-
-
5 繫結使用者與角色關係 - 修改(許可權資料)
-
user/role.jsp
- 表單action
- /system/user?operation=updateRole
- 表單action
-
UserServlet - updateRole方法
-
UserService + UserServiceImpl - updateRole方法
-
UserDao
-
deleteRole
-
updateRole
-
-
UserDao.xml
-
deleteRole
-
updateRole
-
-
1 角色Role + 模組Module :基本CRUD
2 動態載入授權資料(樹形頁面元件)
相當與 許可權資料 回顯
2.1 /WEB-INF/pages/子系統/role/list.jsp
<button type="button" class="btn bg-olive btn-xs"
onclick='location.href="${pageContext.request.contextPath}
/system/role?operation=author&id=${o.id}"'>授權</button>
2.2 RoleServlet新增author方法
private void author(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//獲取要授權的角色id
String roleId = request.getParameter("id");
//使用id查詢對應的資料(角色id對應的模組資訊)
Role role = roleService.findById(roleId);
request.setAttribute("role",role);
//根據當前的角色id獲取所有的模組資料,並載入關係資料
List<Map> map = moduleService.findAuthorDataByRoleId(roleId);
//map轉成json資料
ObjectMapper om = new ObjectMapper();
String json = om.writeValueAsString(map);
request.setAttribute("roleModuleJson",json);
// TODO 資料未查詢
//跳轉到樹頁面中
request.getRequestDispatcher("/WEB-INF/pages/system/role/author.jsp")
.forward(request,response);
}
2.3 author.jsp 定義頁面樹形元件
<SCRIPT type="text/javascript">
// 定義頁面對應的樹形元件
var zTreeObj;
var setting = {check: {enable: true},data: {simpleData: {enable: true}}};
var zNodes =${roleModuleJson}
/*
[
{id:1,pId:0,name:'平臺系統管理',checked:false},
{id:101,pId:1,name:'企業管理',checked:false},
{id:102,pId:1,name:'部門管理',checked:false},
{id:103,pId:1,name:'使用者管理',checked:false},
{id:104,pId:1,name:'角色管理',checked:false},
{id:105,pId:1,name:'模組管理',checked:false},
{id:106,pId:1,name:'系統日誌管理',checked:false},
{id:2,pId:0,name:'題庫管理',checked:false},
{id:201,pId:2,name:'題目學科管理',checked:false},
{id:202,pId:2,name:'題目型別管理',checked:false},
{id:203,pId:2,name:'題目管理',checked:false},
{id:204,pId:2,name:'題目稽核日誌',checked:false},
{id:3,pId:0,name:'會員管理',checked:false},
{id:301,pId:3,name:'會員賬號管理',checked:false},
{id:302,pId:3,name:'會員答題管理',checked:false}
]
*/
$(document).ready(function(){
/*
$.get("${ctx}/system/role?operation=getModuleByRoleId&id=${role.id}",function(data) {
var json = eval('(' + data + ')');
initZtree(json);
});
*/
zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes)
var zTree = $.fn.zTree.getZTreeObj("treeDemo")
zTree.setting.check.chkboxType = { "Y" : "ps", "N" : "ps" }
zTreeObj.expandAll(true);//true:展開所有
});
</SCRIPT>
2.4 ModuleService + ModuleServiceImpl - findAuthorDataByRoleId方法
@Override
public void updateRoleModule(String roleId, String moduleIds) {
SqlSession sqlSession = null;
try{
//1.獲取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.獲取Dao
RoleDao roleDao = MapperFactory.getMapper(sqlSession,RoleDao.class);
//3.呼叫Dao層操作
//修改role_module
//3.1現有的關係全部取消掉
roleDao.deleteRoleModule(roleId);
//3.2建立新的關係(多個)
String[] moduleArray = moduleIds.split(",");
for(String moduleId:moduleArray){
roleDao.saveRoleModule(roleId,moduleId);
}
//4.提交事務
TransactionUtil.commit(sqlSession);
}catch (Exception e){
TransactionUtil.rollback(sqlSession);
throw new RuntimeException(e);
//記錄日誌
}finally {
try {
TransactionUtil.close(sqlSession);
}catch (Exception e){
e.printStackTrace();
}
}
}
2.5 ModuleDao - findAuthorDataByRoleId方法
List<Map> findAuthorDataByRoleId(String roleId);
2.6 ModuleDao.xml - 內容名稱與JSON對應
<select id="findAuthorDataByRoleId" parameterType="string" resultType="java.util.Map">
select
module_id as id,
parent_id as pId,
name as name,
case
when module_id in (select module_id from ss_role_module where role_id = #{roleId})
then 'true'
else 'false'
end
as checked
from
ss_module
</select>
3 繫結角色與模組關係
3.1 WEB-INF\pages\子系統\role\author.jsp
實現許可權分配:選中複選框,授予對應許可權
<SCRIPT type="text/javascript">
//實現許可權分配
function submitCheckedNodes() {
//1.獲取所有的勾選許可權節點
var nodes = zTreeObj.getCheckedNodes(true);//true:被勾選,false:未被勾選
//2.迴圈nodes,獲取每個節點的id,並將資料加入陣列
//1,2,3,4,5 1+","+2+","+3.....
//資料的臨時儲存陣列,為了方便內容連線成為一個由逗號分隔的字串
var moduleArrays = [];
for(var i=0;i<nodes.length;i++) {
moduleArrays.push(nodes[i].id);
}
//3.將陣列中的資料使用,連線後,賦值給表單,傳入後臺
$("#moduleIds").val(moduleArrays.join(',')); //1,2,3,4,5
$("#icform").submit();
}
</SCRIPT>
<form id="icform" method="post" action="${ctx}/system/role?operation=updateRoleModule">
<input type="hidden" name="roleId" value="${role.id}"/>
<input type="hidden" id="moduleIds" name="moduleIds" value=""/>
<ul id="treeDemo" class="ztree"></ul>
</form>
<!--工具欄-->
</form>
3.2 RoleServlet - updateRoleModule 方法
private void updateRoleModule(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String roleId = request.getParameter("roleId");
String moduleIds = request.getParameter("moduleIds");
roleService.updateRoleModule(roleId,moduleIds);
//跳轉回到頁面list
response.sendRedirect(request.getContextPath()+"/system/role?operation=list");
}
3.3 RoleService + RoleServiceImpl - updateRoleModule方法
/**
* 建立角色與模組之間的關聯
* @param roleId 角色id
* @param moduleIds 模組id(多個)
*/
void updateRoleModule(String roleId, String moduleIds);
@Override
public void updateRoleModule(String roleId, String moduleIds) {
SqlSession sqlSession = null;
try{
//1.獲取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.獲取Dao
RoleDao roleDao = MapperFactory.getMapper(sqlSession,RoleDao.class);
//3.呼叫Dao層操作
//修改role_module
//3.1現有的關係全部取消掉
roleDao.deleteRoleModule(roleId);
//3.2建立新的關係(多個)
String[] moduleArray = moduleIds.split(",");
for(String moduleId:moduleArray){
roleDao.saveRoleModule(roleId,moduleId);
}
//4.提交事務
TransactionUtil.commit(sqlSession);
}catch (Exception e){
TransactionUtil.rollback(sqlSession);
throw new RuntimeException(e);
//記錄日誌
}finally {
try {
TransactionUtil.close(sqlSession);
}catch (Exception e){
e.printStackTrace();
}
}
}
3.4 在RoleDao
中新增方法deleteRoleModule
,saveRoleModule
void deleteRoleModule(String roleId);
void saveRoleModule(@Param("roleId") String roleId, @Param("moduleId") String moduleId);
3.5 在對應的對映配置檔案中新增對應的操作
<!--配置根據roleId刪除關係表資料-->
<delete id="deleteRoleModule" parameterType="java.lang.String">
delete from ss_role_module
where role_id = #{roleId,jdbcType=VARCHAR}
</delete>
<!--配置全欄位插入,當某個欄位沒有值時,插入null-->
<insert id="saveRoleModule" parameterType="map">
insert into ss_role_module (role_id, module_id)
values (#{roleId,jdbcType=VARCHAR}, #{moduleId,jdbcType=VARCHAR})
</insert>
4 繫結使用者與角色關係 - 資料(許可權)回顯
4.1 \WEB-INF\pages\子系統\user\list.jsp
- 角色 按鈕 href
- 子系統/user?operation=userRoleList&id="+id
4.2 UserServlet - userRoleList方法 - 將資料傳遞到 角色 頁面
private void userRoleList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userId = request.getParameter("id");
User user = userService.findById(userId);
//將資料載入到指定區域,供頁面獲取
request.setAttribute("user",user);
//獲取所有的角色列表
List<Role> all = roleService.findAllRoleByUserId(userId);
request.setAttribute("roleList",all);
//跳轉頁面
request.getRequestDispatcher("/WEB-INF/pages/system/user/role.jsp")
.forward(request,response);
}
4.3 RoleService + RoleServiceImpl - findAllRoleByUserId方法 - 根據使用者id查詢角色列表
List<Role> findAllRoleByUserId(String userId);
@Override
public List<Role> findAllRoleByUserId(String userId) {
SqlSession sqlSession = null;
try{
//1.獲取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.獲取Dao
RoleDao roleDao = MapperFactory.getMapper(sqlSession,RoleDao.class);
//3.呼叫Dao層操作
return roleDao.findAllRoleByUserId(userId);
}catch (Exception e){
throw new RuntimeException(e);
//記錄日誌
}finally {
try {
TransactionUtil.close(sqlSession);
}catch (Exception e){
e.printStackTrace();
}
}
}
4.4 在dao介面RoleDao
中新增查詢方法findAllRoleByUserId
List<Role> findAllRoleByUserId(String userId);
4.5 在對映配置檔案RoleDao.xml
中新增對應的查詢
<!--配置根據ID查詢-->
<select id="findAllRoleByUserId" parameterType="java.lang.String" resultMap="BaseResultMap">
SELECT
role_id,
NAME,
CASE
WHEN role_id IN (SELECT role_id FROM ss_role_user WHERE user_id = #{'userId'})
THEN 'checked'
ELSE ''
END
AS remark
FROM
ss_role
</select>
4.6 修改頁面/WEB-INF/pages/system/user/role.jsp
,新增checked
<form id="urform" action="${ctx}/system/user?operation=updateRole" method="post">
<input type="hidden" name="userId" value="${user.id}"/>
<div class="textbox" id="centerTextbox">
<div style="text-align:left">
<c:forEach items="${roleList}" var="role" varStatus="vs">
<span style="padding:3px;margin-right:30px;width: 160px;display: inline-block">
<input type="checkbox" name="roleIds" value="${role.id}" ${role.remark}/>${role.name}
</span>
</c:forEach>
</div>
</div>
</form>
5 繫結使用者與角色關係 - 修改(許可權)資料
現在要真正去繫結使用者與角色的關係,前臺頁面提交表單後會將使用者的id和選擇的角色的id傳遞到後臺servlet
5.1 在UserServlet
中新增新的方法
private void updateRole(HttpServletRequest request, HttpServletResponse response) throws IOException {
String userId = request.getParameter("userId");
String[] roleIds = request.getParameterValues("roleIds");
userService.updateRole(userId,roleIds);
//跳轉回到頁面list
response.sendRedirect(request.getContextPath()+"/system/user?operation=list");
}
5.2 在UserService
介面中新增一個新的方法updateRole
void updateRole(String userId, String[] roleIds);
5.3 在對應的實現類 UserServiceImpl 中去實現
@Override
public void updateRole(String userId, String[] roleIds) {
SqlSession sqlSession = null;
try{
//1.獲取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.獲取Dao
UserDao userDao = MapperFactory.getMapper(sqlSession,UserDao.class);
userDao.deleteRole(userId);
for(String roleId : roleIds){
userDao.updateRole(userId,roleId);
}
//4.提交事務
TransactionUtil.commit(sqlSession);
}catch (Exception e){
TransactionUtil.rollback(sqlSession);
throw new RuntimeException(e);
//記錄日誌
}finally {
try {
TransactionUtil.close(sqlSession);
}catch (Exception e){
e.printStackTrace();
}
}
}
5.4 在dao介面UserDao
中新增兩個方法
void deleteRole(String userId);
void updateRole(@Param("userId") String userId, @Param("roleId")String roleId);
5.5 在該介面對應的對映配置檔案中新增兩個操作
<!--配置根據roleId刪除關係表資料-->
<delete id="deleteRole" parameterType="java.lang.String">
delete from ss_role_user
where user_id = #{userId,jdbcType=VARCHAR}
</delete>
<!--配置全欄位插入,當某個欄位沒有值時,插入null-->
<insert id="updateRole" parameterType="map">
insert into ss_role_user (role_id, user_id)
values (#{roleId,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR})
</insert>