基于xml 实现动态加载权限功能树列表---EFSFrame企业级开发架构
在学习EFSFrame框架的过程中,感触最深的就是通过xml来实现前台与后台数据的交互,页面设计灵活,不用管后台如何写的,前台与后台的交互唯一的交互通道都是xml,在我们需要添加页面、添加规定的格式的xml文件就可以很好的融入这个架构中,现自己把加载功能树这一块和大家分享
功能树的加载如图1:
下面是代码实战:
第一步是:这是登陆页面中的html文件中核心的内容:把用户输入的用户名、密码、IP,全部拼接成一个一定格式的xml文件,传给隐藏控件。
function doSubmit()
{
strUserIp = "<% =strUserIP %>";
strUserTitle = document.getElementById("txtUserName").value;
if(strUserTitle == "")
{
alert("用户名不能为空");
return false;
}
strUserPWD = document.getElementById("txtUserPWD").value;
if(strUserPWD == "")
{
alert("密码不能为空");
return false;
}
strMac = document.getElementById("txtMac").value;
//拼接xml文件
strXml = '<?xml version="1.0"?> <EFSFRAME efsframe="urn=www-efsframe-cn" version="1.0"><DATAINFO><LOGININFO><USERTITLE>' + strUserTitle + '</USERTITLE><USERPASSWORD>' + strUserPWD + '</USERPASSWORD><LOGINIP>' + strUserIp + '</LOGINIP><MAC>' + strMac + '</MAC></LOGININFO></DATAINFO></EFSFRAME>';
//通过隐藏控件传到后台
document.getElementById("txtXML").value = strXml; return true;
}
后台的代码,判断信息正确之后调到主页面:
protected void Page_Load(object sender, EventArgs e)
{ if (IsPostBack)
{
try{
//获取到xml的值
string strXml = Request["txtXML"];
// strXml = XmlFun.addXDocHead(strXml);
//创建创建一个doc对象
XmlDocument doc = XmlFun.CreateNewDoc(strXml);
//解析获取xml中的用户名、密码、IP\mac等信息
string strUsertitle = XmlFun.getNodeValue(doc,Common.BAR2 + Common.XDOC_LOGININFO + Common.BAR + Field.USERTITLE);
string strPassWord = XmlFun.getNodeValue(doc, Common.BAR2 + Common.XDOC_LOGININFO + Common.BAR + Field.USERPASSWORD);
string strIP = XmlFun.getNodeValue(doc, Common.BAR2 + Common.XDOC_LOGININFO + Common.BAR + Field.LOGINIP);
string strMac = XmlFun.getNodeValue(doc, Common.BAR2 + Common.XDOC_LOGININFO + Common.BAR + Field.MAC);
//调用相应的sql语句查询方法
string str_SQL = "SELECT * FROM VW_USERLIST WHERE USERTITLE='" + strUsertitle + "'";
string strErr = "";
//创建一个新的对象
ReturnDoc Rtdoc = new ReturnDoc(); OleDbDataReader rst = null;
//判断是否存在这条记录的信息
string strRet = CommonQuery.qryRst(str_SQL, ref rst);
if (strRet == "0")
{
Rtdoc.getQueryInfo(rst);
//判断用户输入的密码是否和数据库中的密码相同 if (strPassWord != Rtdoc.getNodeValue(Common.BAR2 + Field.USERPASSWORD))
{
strErr = "密码错误";
}
}
else
{
strErr = "查询用户信息为空";
} rst.Close(); if(strErr == "")
{
//根据xml信息查找用户的权限信息,并把xml中的信息实例化一个用户的实例对象
UserSession user = new UserSession(Rtdoc.getXml()); string[] arrSys = { user.getUserID(), user.getUserTitle(), user.getUserName(), "", user.getUnitID(), user.getUnitName(), strIP, strMac };
//记录系统日志
string logid = SystemLog.addSysLog(arrSys);
user.setLogID(logid);
//登录信息信息保存用户名、角色 到Session中
Session.Add("RoleUser", user);
//加载主页面
Response.Redirect("Login.aspx");
Response.End();
}
else
{
主页面上显示功能树的div加载带有权限的功能树(分配什么权限只能显示相应的界面信息)
<div iconCls="icon-tree" region="west" width="150" title="功能树" collapsible="true" border="false">
<div region="center" id="treepanel" xtype="treepanel" height="450" autoScroll="true" onEfsClick="doTreeClick()" border="false">
<%--加载设计有权限的树--%>
<div xtype="xmlloader" url="sysadmin/baseRefWeb.aspx?method=getUserRightTree" parentPath="QUERYINFO"></div>
</div>
baseRefWeb.aspx用来加载树
protected void Page_Load(object sender, EventArgs e)
{
try
{
string sMothod = Request["method"];
if (!General.empty(sMothod))
{
Type ts = typeof(baseRef); object obj = Activator.CreateInstance(ts, null); //获得一个实例 object[] methodParamArgs = new object[] { Request, Response }; MethodInfo mi = ts.GetMethod(sMothod); //获得执行方法 string sXml = (string)mi.Invoke(obj, methodParamArgs); //带参数委托方法的调用并返回值 Response.ContentType = "text/xml;charset=utf-8";
Response.Charset = "UTF-8";
//返回读取后权限的xml信息
Response.Write(sXml);
}
}
查询用户权限的公共方法
/// <summary>
/// 查询用户权限
/// </summary>
/// <returns></returns>
public string getUserRightTree(HttpRequest Request, HttpResponse Response)
{
//通过查找角色信息
UserSession userInfo = (UserSession)Session["RoleUser"];
string strTree = userInfo.getUserRightsByUserID();
return strTree;
}
/// 查询出该用户的权限信息
public string getUserRightsByUserID()
{
/// 查询出该用户的权限信息
string str_SQL = Common.SELECT + Common.DISTINCT + Common.ALL +
Common.S_FROM + Table.VW_USERRIGHTTREE +
Common.S_WHERE + Field.USERID + Common.EQUAL + General.addQuotes(this.getUserID()) +
Common.S_ORDER + Field.AFFAIRTYPEID + Common.COMMA + Field.EVENTTYPEID; OleDbDataReader rst_UserRight = null;
try
{
string strRet = CommonQuery.qryRst(str_SQL,ref rst_UserRight); if (strRet != "0")
{
throw new Exception("获得用户权限失败");
} string str_PreAffairTypeID = "";
string str_PreEventTypeID = ""; ReturnDoc doc_RightTree = new ReturnDoc(); XmlDocument doc_tmp = doc_RightTree.getDocument(); XmlElement ele_Root = null;
XmlElement ele_Query = null;
XmlElement ele_AffairType = null; /// 对结果集进行遍历,用来生成功能树
while (rst_UserRight.Read())
{
/// 创建查询返回节点
if (!doc_RightTree.createQueryInfoNode())
{
throw new Exception("UserCache.setUserRightsByUserID.创建查询返回节点时发生错误");
} /// if (!doc_RightTree.createQueryInfoNode()) ele_Root = ele_Root == null ? (XmlElement)doc_RightTree.getQueryInfoNode() : ele_Root; string str_AffairTypeID = rst_UserRight[Field.AFFAIRTYPEID].ToString();
string str_AffairTypeName = rst_UserRight[Field.AFFAIRTYPENAME].ToString();
string str_EventTypeID = rst_UserRight[Field.EVENTTYPEID].ToString();
string str_EventTypeName = rst_UserRight[Field.EVENTTYPENAME].ToString();
string str_OpURL = rst_UserRight[Field.OPURL].ToString(); int int_AffairTypeID = Convert.ToInt32(str_AffairTypeID); XmlElement ele_EventType = null; /// 查询事务
if (int_AffairTypeID == 4)
{
ele_AffairType = doc_tmp.CreateElement(Common.XDOC_OPERATION);
ele_AffairType.SetAttribute(Common.XML_PROP_AFFAIRTYPEID, str_AffairTypeID);
ele_AffairType.SetAttribute(Common.XML_PROP_NAME, str_AffairTypeName); ele_Query = ele_AffairType;
ele_Root.AppendChild(ele_AffairType);
} /// if (int_AffairTypeID==4)
else
{
if (!str_PreAffairTypeID.EndsWith(str_AffairTypeID))
{
ele_AffairType = doc_tmp.CreateElement(Table.AFFAIRTYPE);
ele_AffairType.SetAttribute(Common.XML_PROP_AFFAIRTYPEID, str_AffairTypeID);
ele_AffairType.SetAttribute(Common.XML_PROP_TEXT, str_AffairTypeName); str_PreAffairTypeID = str_AffairTypeID;
ele_Root.AppendChild(ele_AffairType);
}
} /// 相同的事件类型,则不用重复创建
if (!str_PreEventTypeID.Equals(str_EventTypeID))
{
ele_EventType = doc_tmp.CreateElement(Table.EVENTTYPE);
ele_EventType.SetAttribute(Common.XML_PROP_EVENTTYPEID, str_EventTypeID);
ele_EventType.SetAttribute(Common.XML_PROP_TEXT, str_EventTypeName);
ele_EventType.SetAttribute(Common.XML_PROP_OPURL, str_OpURL);
ele_AffairType.AppendChild(ele_EventType);
str_PreEventTypeID = str_EventTypeID;
} /// if (!str_PreEventTypeID.equals(str_EventTypeID))
} /// while (rst_UserRight.next()) /// 将查询事务节点,追加到权限功能树的最后
if (ele_Query != null)
{
XmlElement ele_TempQuery = (XmlElement)ele_Query.Clone();
XmlElement ele_QueryInfo = (XmlElement)doc_RightTree.getQueryInfoNode();
ele_QueryInfo.RemoveChild(ele_Query);
ele_QueryInfo.AppendChild(ele_TempQuery);
} /// if (ele_Query!=null) if (!doc_RightTree.addErrorResult(Common.RT_QUERY_SUCCESS))
{
throw new Exception("添加函数返回结果失败");
} /// if (!doc_RightTree.addErrorResult(Common.RT_QUERY_SUCCESS)) return doc_RightTree.getXml();
}
catch (Exception e)
{
return e.Message;
}
finally
{
rst_UserRight.Close();
}
}
这是通过浏览器的网络查到返回的数据信息
经过页面解析就有了刚开始这样功能树:
这样就实现了我们所要的功能树(所属某个角色权限)
总结:
刚开始接触这个框架的时候确实看不太懂,后面深入的调试之后发现很强大、灵活,角色、功能的添加每个都是有一个xml来对应的控制,特别是对字典表的管理,当用户添加字典表之后,会根据数据库的内容生产字典文件到xml文件,页面加载的时候是页面从对应的xml文件读取的,并非数据库中查询加载,这样大大提高了页面加载数据的效率,软件的用户体验度很好,对于大数据量的解决提供了好的思路。
我们见识的知识还很少,我们到现在这个阶段,更多的应该是站在巨人的肩膀之上来拓展我们的学习思路,总结前人好的学习方法、思路,为进一步的学习架构指导方向。
基于xml 实现动态加载权限功能树列表---EFSFrame企业级开发架构的更多相关文章
- shiro不重启动态加载权限
最近一朋友让我帮他做一个后台权限管理的项目.我就在我原来的项目加加改改但是还是不理想,查了不少资料也走了不了弯路...... shiro基本的配置我就不多说了这个很简单自己查查资料就完成----下面是 ...
- SpringBoot集成Shiro 实现动态加载权限
一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...
- C#遍历XML文件动态加载菜单
通过遍历XML文件动态加载菜单,顺便利用WebBrowser控件实现一个简单的桌面浏览器 效果如下: 代码如下: XMLFile1.xml <?xml version="1.0&quo ...
- android sax解析xml 文件 动态加载标题
要解决一个问题 : 问题描述为 把标题动态的加载到 listView子布局中 我们首先通过 java程序写一个把标题写到xml文件的程序.这个程序会在以后讲解. 现在截图 已经写好的xm文件格式如下 ...
- 动态加载下拉框列表并添加onclick事件
1. js动态加载元素并设置属性 摘自(http://www.liangshunet.com/ca/201408/336848696.htm) <div id="parent&quo ...
- 6.0动态加载权限用PermissionGen
ndroid 6.0 新增加了运行时的动态添加权限,在此介绍一个第三方库,PermissionGen,可以很方便简洁的增加 6.0权限 首先给大家上 PermissionGen 库地址:https: ...
- 中文分词实战——基于jieba动态加载字典和调整词频的电子病历分词
分词是自然语言处理中最基本的一个任务,这篇小文章不介绍相关的理论,而是介绍一个电子病历分词的小实践. 开源的分词工具中,我用过的有jieba.hnlp和stanfordnlp,感觉jieba无论安装和 ...
- Android中插件开发篇之----动态加载Activity(免安装运行程序)
一.前言 又到周末了,时间过的很快,今天我们来看一下Android中插件开发篇的最后一篇文章的内容:动态加载Activity(免安装运行程序),在上一篇文章中说道了,如何动态加载资源(应用换肤原理解析 ...
- [AngularJS] 使用AngularCSS动态加载CSS
[AngularJS] 使用AngularCSS动态加载CSS 前言 使用AngularAMD动态加载Controller 使用AngularAMD动态加载Service 上列两篇文章里,介绍了如何如 ...
随机推荐
- Jenkins的关闭、重启
以前一直用从cmd进入jenkins的安装目录,执行jenkins stop/start,但是新的jenkins有更加方便功能 关闭jenkins服务 只需要在访问jenkins服务器的网址url地址 ...
- SQL注入原理及绕过安全狗
1.什么是SQL注入攻击 SQL注入攻击指的是通过构造特殊的输入作为参数插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令 http://www.xxx.com/list. ...
- .NET中的各种池
在.NET中,常用到的池有四个:字符串拘留池.线程池 .应用程序池.数据库连接池. 字符串拘留池 在.NET中字符串是不可变对象,修改字符串变量的值会产生新的对象.为降低性能消耗及减小程序集大小,.N ...
- ACM 人见人爱A^B
求A^B的最后三位数表示的整数. 说明:A^B的含义是"A的B次方" Input输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10 ...
- MongoDB 监控
在你已经安装部署并允许MongoDB服务后,你必须要了解MongoDB的运行情况,并查看MongoDB的性能.这样在大流量得情况下可以很好的应对并保证MongoDB正常运作. MongoDB中提供了m ...
- Docker容器的运用
Docker 利用容器来运行应用. 容器是从镜像创建的运行实例.它可以被启动.开始.停止.删除.每个容器都是相互隔离的.保证安全的平台. 可以把容器看做是一个简易版的 Linux 环境(包括root用 ...
- OC基础之可循环滚动并突出中间图片,并且可点击
前两天一哥们儿让我帮他写一下:可循环滚动并突出中间图片,并且可点击的一种滑动视图的效果,今天放在这里给大家展示一下,具体文字代码中都有注解,代码还有待完善,不喜勿喷,转载请注明,下载请点星,谢谢~ - ...
- Java经典设计模式之七大结构型模式(附实例和详解)
博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以上的猿友阅读起来才会理解的比较深刻.当然,你没 ...
- 从Dynamics CRM2011到Dynamics CRM2016的升级之路
CRM的产品更新特别快,特别是最近的几个版本,很多客户依旧停留在2011甚至是4.0,也经常会听到有人问2011能不能升级至最新版,2013能不能升级至最新版,本文将简单演示下从2011升级到2016 ...
- Azkaban-2.5及Plugins的安装配置
Azkaban是由LinkedIn开发的调度工具,可以用于调度Hadoop中的相互依赖的Job.有时候,在Hadoop集群中运行的Job是相互依赖的,某些任务需要顺序的执行,这种场景下使用Azkaba ...