您的位置:首页 > 编程语言 > Java开发

spring MVC权限分配的实现

2016-05-13 15:26 543 查看
多数业务系统的页面功能菜单设计是以三级为标准的,即一级功能菜单、二级功能菜单、三级功能菜单,通常情况下一二级功能菜单只是用于功能分类,是不具有功能访问地址的,三级菜单才是功能的真正入口,常规权限系统就是通过控制每个人员对应的功能菜单的显示与隐藏来实现权限控制。要实现细粒度权限控制,可在设计功能表时再加入第四层:页面元素,隶属于第三层功能菜单,这些页面元素用来标识功能页面中的每一个功能按钮,如增加、修改、删除、查询都可算是页面元素,在为角色分配权限时,第四层也同样纳入统一权限管理,如果有此页面元素的权限,则页面上就显示该按钮,如果没有此页面元素的功能权限,则该按钮就不会显示出来。



以上阐述引用自:http://blog.csdn.net/ycyk_168/article/details/18456631

以下主要讲解上述功能的实现:

登录信息的验证:SecurityConroller.java

@RequestMapping(value = { "/login", "/index" }, method = RequestMethod.POST)
public ModelAndView doLogin(HttpSession session, LoginForm loginForm) {
User user = userService.getUserByLoginName(loginForm.getLoginName()
.trim());

if (user != null && user.getPwd().equals(loginForm.getPwd())) {
session.setAttribute("user", user);
List<String> rights=userService.getRights(user.getId());
session.setAttribute("rights",rights);
session.setAttribute("onlineUserBindingListener", new OnlineUserBindingListener(user));
return new ModelAndView("redirect:/mainFrame.htm");
} else {
//result.reject("", "用户名或者密码不正确");
ModelAndView mv=new ModelAndView();
mv.setViewName("/login_new");
mv.addObject("loginFail", true);
return mv;
}
}


User类中包括 用户姓名 密码 id 等信息。

通过 user_id 获取该用户的功能权限。

UserService.java

@SuppressWarnings("unchecked")
public List<String> getRights(Long id) {
return this.hibernateTemplate.find("select distinct gr.function.url from GroupRight as gr where gr.group.id in
(select ug.group.id from UserGroup as ug where ug.user.id=?)",id);
}


用户组类:UserGroup 其中包含id group_id user_id 三个字段

权限组类: GroupRight 其中包含 id group_id function_id

function 类:其中包含 id name url functionCategory 等字段。

group类:包含id name两个属性。

user类:id name 所属部门等个人信息。

逻辑关系: group_id<--------------------UserGroup----------------->user_id

group_id<--------------------GroupRight------------------>function_id

即: 通过 user. id------> UserGroup------>group_id -------->GroupRight----->function---->function.url

注意:一个用户可以隶属于 多个用户组,对用户组分配权限。(功能分类只针对用户组)

功能隶属于 功能分类,(功能分类,方便管理,如果功能项很多,在管理用户分配权限的时候不方便)

与用户组关联的,是功能,而不是功能分类。

上述过程,完成用户功能的查询。以下讲解,对查询出的功能的实现。

从上述的SecurityController.java中可以知道,请求转到mainFrame.html,由于作者前台使用 Frame框架,因此,具体跳转过程不再讲述。

以下讲解对menu的控制:

MainFrameController.java

<span style="color:#ff0000;">
</span>@SuppressWarnings("unchecked")
@RequestMapping(value = "/menu")

public ModelAndView menu(HttpSession session) throws Exception {

//testMain tm=new testMain();
User user = (User) session.getAttribute("user");
ModelAndView mv = new ModelAndView();
if (user.getLoginName().equals("admin")) {
mv.setViewName("/adminMenu");
//mv.setView(null);
}
else <span style="color:#ff0000;">
</span>{
MenuBuilder builder = new MenuBuilder("/menus/menus.xml");
Menu menu = builder.getMenu();
List<String> rights=(List<String>) session.getAttribute("rights");

//menu.removeSubMenu(rights);

if (!user.getType().equals("a")){
menu.removeSubMenu(rights);
}

mv.setViewName("/userMenu");

String	childZNode1="{ id:10000, pId:0, name:'用户功能'},";
String	childZNode2="{ id:1000001, pId:10000, name:'查看个人资料', url:'viewSelf.htm', target:'mainFrame'},";
String	childZNode3="{ id:1000002, pId:10000, name:'修改密码', url:'changePwd.htm', target:'mainFrame'},";
String	childZNode4=null;
if(user.getType().equals("a")){
childZNode4="{ id:1000003, pId:10000, name:'修改所属部门', url:'changeDepartment.htm', target:'mainFrame'}";
mv.addObject("menu", "["+menu.toString()+childZNode1+childZNode2+childZNode3+childZNode4+"]");
}
else{
mv.addObject("menu", "["+menu.toString()+childZNode1+childZNode2+childZNode3+"]");
}

}
return mv;

}



将xml文件中的url 移除掉不包含在rights中的项,由menu.removeSubMenu(rights)实现;

以上xml文件中,部分内容:

<?xml version="1.0" encoding="UTF-8"?>
<menus>

<menu name="项目评估处理">
<menu name="待完成工作">
<menu name="待完成工作查询" url="user/task/tasklist.htm">
</menu>
</menu>
<menu name="信息录入">
<menu name="资料录入" url="user/project/1/add.htm">
</menu>
<menu name="资料查询" url="user/project/1/list.htm">
</menu>
</menu>
<menus>


menu.java

<span style="color:#ff0000;">	</span>public void removeSubMenu(List<String> rights)
{
List<Menu> removed=new ArrayList<Menu>();
for(Menu subMenu:subMenus)
{
if(subMenu.url!=null)
{
if(!rights.contains("/"+subMenu.url))
removed.add(subMenu);
}else
{
subMenu.removeSubMenu(rights);
if(subMenu.subMenus.size()==0)
{
removed.add(subMenu);
}
}
}
subMenus.removeAll(removed);
}


menu.java
/*动态生成 Z树-----*/
public String toString() {
StringWriter sw = new StringWriter();
PrintWriter writer = new PrintWriter(sw);
if (parentId != -1) {

String mainFrame1="mainFrame";
if (url != null && parameter != null) {
writer.printf("{id:%d,pId:%d, name:\"%s\", url:\"%s?%s\",target:\"%s\"},", id, parentId,
name, url, parameter,mainFrame1);
} else if (url != null && parameter == null) {
writer.printf("{id:%d,pId:%d, name:\"%s\", url:\"%s\",target:\"%s\"},", id, parentId,
name, url,mainFrame1);
} else if (url == null) {
writer.printf("{id:%d,pId:%d, name:\"%s\",target:\"%s\"},", id, parentId,
name,mainFrame1);
}
}
StringBuffer buffer = sw.getBuffer();

for (Menu menu : subMenus) {
buffer.append(menu.toString());
}
return buffer.toString();
}


userMenu,jsp部分代码:

var zNodes=${menu};<span style="color:#ff0000;">

</span>$(document).ready(function(){
var treeObj = $("#treeDemo");
$.fn.zTree.init(treeObj, setting, zNodes);
zTree_Menu = $.fn.zTree.getZTreeObj("treeDemo");
curMenu = zTree_Menu.getNodes()[0].children[0].children[0];
zTree_Menu.selectNode(curMenu);
treeObj.hover(function () {
if (!treeObj.hasClass("showIcon")) {
treeObj.addClass("showIcon");
}
}, function() {
treeObj.removeClass("showIcon");
});
关于Z-tree的使用,这里不再阐述。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: