javaweb权限管理简单实现_javaweb管理系统项目

news2024/9/23 4:04:38

最近在做一个网站类型项目,主要负责后台,ui框架选型为jquery easy ui,项目架构为spring mvc + spring jdbc,简单易用好上手!搭建好框架后开始了第一个任务,设计并实现一套简单的权限管理功能。

一套最基本的权限管理包括用户、角色、资源。

数据库设计

我的设计如下:

用户:user

角色:role

用户-角色:user_role

资源:resource(包括上级菜单、子菜单、按钮等资源)

角色-资源:role_resource

标准的权限管理系统设计为以上5张表。

注:用户、用户-角色我就不做说明了,这两个是很简单的两块,用户的crud,以及为用户分配角色(多对多的关系)稍微琢磨一下就清楚了,下面都是针对为角色分配权限的实现

效果图:

项目结构

后台实现

展示层采用ztree树

role.jsp

<%@ page contentType="text/html;charset=UTF-8"%>
<%@ include file="/views/back/include/taglib.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="decorator" content="back" />
<script type="text/javaScript">
//打开菜单窗口
function openMenuDialog(){
var selected = $("#list").datagrid('getSelected');
if (selected != null) {
$("#id").val(selected.id);
queryMenus(selected.id);
$("#menuWindow").window("open");
} else {
$.messager.alert('提示', "未选择数据!"); 
}
}
//角色-菜单信息入库
function ajaxSubmit(rid,idstr){
$.post("${ctx}/roleMenu/save.jhtml",{"roleId":rid,"ids":idstr},function(obj){
$.messager.alert('提示',obj.msg);
$("#menuWindow").window('close');
},'json');
}
</script>
<!-- ztree -->
<script type="text/javascript">
var tree = "";
var setting = {
check : {
chkboxType:{"Y":"ps","N":"s"},//勾选checkbox对于父子节点的关联关系,取消勾选时不关联父
chkStyle:"checkbox",
enable : true	//是否复选框
},
//数据
data : {
simpleData : {
enable : true
}
}
};
//查询菜单信息
function queryMenus(roleId){
$.post('${ctx}/role/treedata.jhtml', {'roleId':roleId}, function(zNodes) {
for (var i = 0; i < zNodes.length; i++) {
if (zNodes[i].isParent) {
} else {
//zNodes[i].icon = "${ctxStatic}/images/532.ico";//设置图标
}
}
tree = $.fn.zTree.init($("#tree"), setting, zNodes);
tree.expandAll(true);//全部展开
//var nodes = treeObj.getNodes();
}, 'json');
}
//获取选中节点
function onCheck(){
var rid = $("#id").val();
var treeObj=$.fn.zTree.getZTreeObj("tree");
var nodes=treeObj.getCheckedNodes(true);
var ids = new Array();
for(var i=0;i<nodes.length;i++){
//获取选中节点的值
ids.push(nodes[i].id);
// v+=nodes[i].id + ",";
//alert(nodes[i].id); 
}
ajaxSubmit(rid,ids);     
}
</script>
</head>
<body>
<!-- 数据表格 -->
<table id="list" url='${ctx}/role/list/page.jhtml' method='post'
class="easyui-datagrid" style="width:100%;" fitcolumns="true" 
toolbar='#tb' pagination='true' rownumbers='true' singleSelect='true'>
<thead>
<tr>
<th field='name' sortable='true' width='100'>角色名称</th>
<th field='description' width='200' align='right'>描述</th>
<th field='createTimeFormat' width='150' align='center'>创建时间</th>				
</tr>
</thead>
</table>
<!-- 编辑栏  -->
<div id="tb" style="padding:5px 5px;">
<div>
<p2p:permission module="role" code="add"><a href="#" class="easyui-linkbutton" iconCls="icon-add" onclick="openCreateDialog();">新增</a></p2p:permission>
<p2p:permission module="role" code="edit"><a href="#" class="easyui-linkbutton" iconCls="icon-edit" onclick="openUpdateDialog();">编辑</a></p2p:permission>
<p2p:permission module="role" code="delete"><a href="#" class="easyui-linkbutton" iconCls="icon-remove" onclick="del();">删除</a></p2p:permission>
<p2p:permission module="role" code="authority"><a href="#" class="easyui-linkbutton" iconCls="icon-edit" onclick="openMenuDialog();">设置权限</a></p2p:permission>
</div>
<!-- 搜索项 -->
<div style="margin-top:5px;padding-left:5px">
用户名:   <input id="query_name" class="easyui-textbox" type="text" style="width:110px" />
创建日期: <input id="query_startDate" class="easyui-datebox" style="width:110px">
至: 	   <input id="query_endDate" class="easyui-datebox" style="width:110px">
<a onclick="reload();" href="#" class="easyui-linkbutton" iconCls="icon-search">查询</a>
</div>
</div>
<!-- 权限窗口 -->
<div id="menuWindow" class="easyui-window" title="配置权限" data-options="modal:true,iconCls:'icon-save',footer:'#menuWindowfooter'" style="width:350px;height:420px;padding:10px">
<div id="tree" class="ztree" style="padding: 10px 20px;"></div>
</div>
<div id="menuWindowfooter" style="padding:5px;text-align:right;"> 
<a href="#" onclick="onCheck();" class="easyui-linkbutton" data-options="iconCls:'icon-save'">提交</a>
</div>
</body>
</html>

action层 RoleAction.java

@RequestMapping(value = "/treedata.jhtml")
@ResponseBody
public String treedata(HttpServletRequest request, Model model) {
DynamicParams params = new DynamicParams(request);
List<Map<String, Object>> mapList = Lists.newArrayList();
params.put("allMenu", "allMenu");
List<Menu> list = authManager.findMenuList(params);
List<RoleMenu> roleMenus = authManager.findRoleMenuList(params);
for (int i = 0; i < list.size(); i++) {
Menu e = list.get(i);
Map<String, Object> map = Maps.newHashMap();
map.put("id", e.getId());
map.put("pId", e.getParentId() != null ? e.getParentId() : 0);
map.put("name", e.getName());
for (RoleMenu roleMenu : roleMenus) {
if (roleMenu.getMenuId() == e.getId()) {
map.put("checked", true);
}
}
mapList.add(map);
}
return toJson(mapList);
}

service层

AuthManager.java

/**
* 去除菜单中重复项
* 
* @param list
* @return
*/
private List<Menu> removeDuplicate(List<Menu> list) {
List<Menu> result = new ArrayList<Menu>();
Set<Long> menuIds = new HashSet<Long>();
for (int i = 0; i < list.size(); i++) {
Menu m = list.get(i);
if (m != null && menuIds.add(m.getId())) {
result.add(m);
}
}
return result;
}

public List<RoleMenu> findRoleMenuList(DynamicParams params) {
List<RoleMenu> roleMenus = roleMenuDao.findList(params);
return roleMenus;
}

Dao层

menuDao

@Override
protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
sql.append("select s.* from sys_menu s where 1=1 ");
String parentId = params.getString("parentId");
if (StringUtils.isNotBlank(parentId)) {
sql.append(" and parent_id = ? ");
args.add(parentId);
}
String sort = params.getString("sort");
String order = params.getString("order");
if (StringUtils.isNotBlank(sort)) {
sql.append(" order by ").append(hump2underline(sort));
if (StringUtils.isNotBlank(order)) {
sql.append(" " + order);
} else {
sql.append(" desc ");
}
} else {
sql.append("order by sort asc,id desc ");
}
}

userRoleDao

@Override
protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
sql.append("select s.* from sys_user_role s where 1=1 ");
Long adminId = params.getLong("adminId");
if (adminId != null) {
sql.append(" and s.user_id = ?");
args.add(adminId);
}
}

roleMenuDao

@Override
protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
sql.append("select s.* from ").append("sys_role_menu").append(" s where 1=1 ");
Long adminId = params.getLong("roleId");
if (adminId != null) {
sql.append(" and s.role_id = ?");
args.add(adminId);
}
}

在WEB-INF目录下建立文件夹tlds 建立自定义标签文件shiros.tld,我们通过自定义标签实现页面按钮的控制。

<span style="color:#333333;"><?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>p2p permission taglib</description>
<display-name>permission taglib</display-name>
<tlib-version>1.0</tlib-version>
<short-name>p2p_back</short-name>
<uri>http://vanfon.p2p.cn/</uri>
<tag>
<description>权限校验标签,有权限就显示标签体的内容,否则不显示</description>
<name>permission</name>
<tag-class>com.vanfon.p2p.back.tag.PermissionTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<description></description>
<name>module</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<description></description>
<name>code</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib></span>

自定义标签类

package com.vanfon.p2p.back.tag;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import com.vanfon.p2p.entity.system.Admin;
import com.vanfon.p2p.entity.system.Menu;
import com.vanfon.p2p.manager.system.AuthManager;
import com.vanfon.p2p.utils.DynamicParams;
import com.vanfon.p2p.utils.SpringContextHolder;
/**
* 权限控制标签
* 
* @author zhangwx
* @date 2015-2-5
*/
public class PermissionTag extends TagSupport {
/**
* 
*/
private static final long serialVersionUID = 4592227792811389132L;
private String module;// 属性名必须与JSP自定义标签的属性名一样
private String code;
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public int doStartTag() throws JspException {
boolean result = false;
HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest();// 通过成员变量获取HttpServletRequest对象
Admin admin = (Admin) request.getSession().getAttribute("admin");// 获取登录到系统的用户
if (admin != null) {
if ("1".equals(String.valueOf(admin.getIfsuper()))) {// 超级管理员
result = true;
} else {
DynamicParams params = new DynamicParams();
params.put("id", String.valueOf(admin.getId()));
params.put("module", this.module);
params.put("code", this.code);
AuthManager authManager = SpringContextHolder.getBean(AuthManager.class);
List<Menu> userRoleAuths = authManager.findUserRoleAuthList(params);
if (userRoleAuths != null && userRoleAuths.size() > 0) {
result = true;
}
}
}
return result ? EVAL_BODY_INCLUDE : SKIP_BODY;
}
}

以上就是该权限管理中权限树(为角色分配权限)的大体实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/479944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习第J8周:Inception v1算法实战与解析

目录 一、Inception v1 1.简介 2. 算法结构 二、pytorch代码复现1.前期准备 2.代码复现 3.训练运行 3.2指定图片进行预测 三、总结 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作…

ChatGPT登陆方法及常见问题

Chatgpt现在推出ChatGPT Plus服务&#xff0c;所以对注册账号限制比较大 Plus账号有什么优势&#xff1f; 我们可以看到官方介绍&#xff1a; 优势1 Available even when demand is high 当访问量大时&#xff0c;依旧可以访问 优势2 Faster response speed 更快的回复速度…

无云服务器,Linux本地快速搭建web网站,并内网穿透发布上线

文章目录 前言1. 本地搭建web站点2. 测试局域网访问3. 公开本地web网站3.1 安装cpolar内网穿透3.2 创建http隧道&#xff0c;指向本地80端口3.3 配置后台服务 4. 配置固定二级子域名5. 测试使用固定二级子域名访问本地web站点 转载自cpolar文章&#xff1a;Linux CentOS本地搭建…

医疗器械的分类与查询

我国根据医疗器械产品安全性对医疗器械进行分类管理。分类目录由国家食品药品监督管理部门依据医疗器械分类规则制定&#xff1a; 第一类是风险程度低&#xff0c;实行常规管理可以保证其安全、有效的医疗器械。如&#xff1a;外科用手术器械&#xff08;刀、剪、钳、镊、钩&a…

RabbitMQ 工作队列模式 Work Queue Demo

工作队列模式,一个消息只能有一个消费者消费 生产者发送20条消息 消费者有两个 第一个消费 睡一秒取一个 第二个睡2秒取 public class WorkConsumerTest1 {public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactor…

「华熙生物」发来感谢信,企企通赋能生物科技领域数字化采购建设

近日&#xff0c;华熙生物科技股份有限公司&#xff08;以下简称“华熙生物”&#xff09;携手企企通打造的数字化采购管理平台成功上线。为感谢企企通在采购数字化项目上的付出和努力&#xff0c;华熙生物特意发来暖心感谢信。 在感谢信中&#xff0c;华熙生物表示&#xff1a…

【目标检测实验系列】YOLOv5改进实验:结合VariFocal Loss损失函数,减少小目标漏检问题,高效提升模型检测的召回率(超详细改进代码流程)

目录 1. 文章主要内容2. VariFocal Loss损失函数&#xff08;原理&#xff1a;简单介绍&#xff0c;可自行详细研究&#xff09;2.1 VariFocal Loss损失函数2.2 博主数据集实验效果 3. 代码详细改进流程(重要)3.1 新建varifocalLoss.py文件3.2 修改hyp.scratch-low.yaml文件3.3…

【MATLAB图像处理实用案例详解(20)】——利用BP神经网络实现人脸朝向判断

目录 一、问题描述二、算法步骤2.1 读入数据并提取特征2.2 创建神经网络并训练2.3 测试 三、结果分析 一、问题描述 BP神经网络利用输出后的误差来估计输出层的直接前导层的误差&#xff0c;再用这个误差估计更前一层的误差&#xff0c;如此一层一层的反传下去&#xff0c;就获…

4_用dockerfile制作镜像

Docker 镜像原理 思考&#xff1a; Docker 镜像本质是什么&#xff1f; Docker 中一个centos镜像为什么只有200MB&#xff0c;而一个centos操作系统的iso文件要几个个G&#xff1f; Docker 中一个tomcat镜像为什么有500MB&#xff0c;而一个tomcat安装包只有70多MB&#xff…

JavaScript中的Concurrency并发:异步操作下的汉堡制作示例

这篇文章想讲一下JavaScript中同步与异步操作在一个简单的示例中的应用。我们将以制作汉堡为例&#xff0c;展示如何使用同步方法、回调函数&#xff08;callbacks&#xff09;和Promise与async/await来实现该过程。 Let’s imagine we’re trying to make a burger: 1. Get …

基于simulink使用混合波束成形对射频毫米波发射器进行建模

一、前言 本例说明了一种使用66元件混合波束成形天线对32 GHz QPSK射频发射和接收系统进行系统级建模和仿真的方法。该系统包括射频缺陷、发射阵列辐射效应、窄带接收阵列和基带接收器&#xff0c;可校正系统损伤和消息解码。天线波束形成方向使用方位角和仰角定义&#xff0c;…

C语言CRC-16 USB格式校验函数

C语言CRC-16 USB格式校验函数 CRC-16校验产生2个字节长度的数据校验码&#xff0c;通过计算得到的校验码和获得的校验码比较&#xff0c;用于验证获得的数据的正确性。基本的CRC-16校验算法实现&#xff0c;参考&#xff1a; C语言标准CRC-16校验函数。 不同应用规范通过对输…

计算机图形辐照度学、光度学

文章目录 前言&#xff1a;一、什么是辐照度学二、什么是光度学 前言&#xff1a; 在计算机图形学中是把辐射(Radiance)等概念和亮度(Luminance)等概念不做区分的。辐射是辐照度学的概念&#xff0c;而亮度则是光度学上的概念。 辐照强高度并不意味着亮度就强&#xff0c;就比如…

VTK 几何体连通区域分析 vtkPolyDataConnectivityFilter

前言&#xff1a; vtkPolyDataConnectivityFilter 使用过&#xff0c;但网上没有看到完事的教程&#xff1b;这里整理一下&#xff1b; 提取数据集中连通的多边形数据。 该类是一个滤波器&#xff0c;提取cell&#xff08;区域&#xff09; - 拥有公共点或者满足某个阈值 该类…

Soft-RoCE部署及通信测试

Soft-RoCE部署及通信测试 Soft-RoCE是一种基于软件的RoCE&#xff08;RDMA over Converged Ethernet&#xff09;实现。RoCE是一种在以太网上实现RDMA&#xff08;Remote Direct Memory Access&#xff09;的技术&#xff0c;它允许数据在网络中直接传输&#xff0c;而无需CPU…

【ElasticSearch】几点优化及面试相关

文章目录 硬件选择分片策略合理设置分片数推迟分片分配 路由选择写入速度优化(磁盘优化)批量数据提交优化存储设备合理使用合并减少 Refresh 的次数加大 Flush 设置减少副本的数量 内存设置ES配置文件解析Elasticsearch 面试题为什么要使用 Elasticsearch?Elasticsearch 的 ma…

【Java网络编程】基于UDP-Socket 实现客户端、服务器通信

​ 哈喽&#xff0c;大家好~我是你们的老朋友&#xff1a;保护小周ღ 本期为大家带来的是网络编程的 UDP Socket 套接字&#xff0c;基于 UDP协议的 Socket 实现客户端服务器通信&#xff0c;Socket 套接字可以理解为是&#xff0c;传输层给应用层提供的一组 API&#xff0c;…

Java中提升接口性能的一些方法

目录 1.使用线程池并行执行2.数据库优化2.1 小表关联大表2.2 反三大范式操作2.3 增加索引2.4 减小事务粒度2.5 读写分离、分库分表 3.拥抱缓存3.1 Redis3.2 内存缓存 4.锁和异步4.1 减小锁的粒度4.2 分布式锁 1.使用线程池并行执行 假如有一个接口的逻辑如下&#xff1a; 接口…

cadence遇到的问题

1、最烦人的&#xff0c;突然卡住。 设置grid卡住&#xff0c;导出libraries卡住&#xff0c;选择其他产品时卡住。 从微软拼音输入法改成美式键盘后能解决一些问题。但不能解决全部。 今天下载了搜狗输入法来替代微软自带输入法。效果奇佳&#xff0c;真的可以诶。 2、如果…

沁恒 CH32V208(一): CH32V208WBU6 评估板上手报告和Win10环境配置

目录 沁恒 CH32V208(一): CH32V208WBU6 评估板上手报告和Win10环境配置 CH32V208 CH32V208系列是沁恒32位RISC-V中比较新的一个系列, 基于青稞RISC-V4C内核, 最高144MHz主频, 64KB SRAM&#xff0c;128KB Flash, 供电电压2.5/3.3V. 这个型号的特点: 除了特有的硬件堆栈区、…