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

extjs springMVC实现动态树形菜单

2014-11-08 22:28 477 查看
最近由于项目需要,做一个树形动态菜单,用extjs3 来做,结合springMVC,实现从后台动态的加载数据形成权限菜单。

一、数据表设计

首先是数据库的设计,数据库表是一张权限表(即菜单表),我把它设计成一张递归表,实现能显示父级菜单和子菜单的树形菜单,

表的设计如下:



使用pri_Id为外键,引用本表的主键,实现一张递归表。

二、Java代码中po类的设计

po类的设计对应数据表中的数据(除了外键),用于做传送数据用。

private Integer id;//节点id
private String text;//节点名称
private boolean leaf;//是否为子节点
private String url;//节点点击的请求路径
private String cls;//节点的图标,folder还是file
private Privilige parent;//父级菜单
private Set<Privilige> children = new HashSet<Privilige>();//子菜单
//getter...setter
注意字段的名字不能变,因为返回json数据给前台时extjs会自动识别并加载。

三、前台extjs的jsp界面

Ext.QuickTips.init();//显示提示信息
//树加载器
var treeLoader = new Ext.tree.TreeLoader(
{
//获取数据库的远程地址
dataUrl:"${pageContext.request.contextPath }/Menu/showAllMenu"
});
//当点击节点时传递节点id到服务器端上
treeLoader.on("beforeload",function(treeLoader,node){
this.baseParams.nodeId = node.id;
});
//定义树
var tree = new Ext.tree.TreePanel({
id : 'tree',
animate : true,
autoScroll : true,
containerScroll : true,
lines : true,
rootVisible:false,//不显示根节点
loader:treeLoader,//加载后台数据的树加载器
expanded:true,
//根节点要用AsyncTreeNode
root: new Ext.tree.AsyncTreeNode({
expanded: true,
text:"系统菜单",
id:"0",
leaf:false
})
});

四、设计privilige接口及实现类

public interface PrivilegeService {

/**
* 根据父级菜单的id获取其下的子菜单
*/
List<Privilige> getMenuByParentId(Integer pid);

/**
* 判断用户是否拥有某项权限
* @param sysOper 登陆的操作员
* @param menuId 权限对应的id
*/
boolean hasPermission(Systemoper sysOper,Integer menuId);

/**
* 判断角色是否拥有某项权限
*/
boolean hasPermission(Role role,Integer menuId);

/**
* 返回全部权限(菜单)数据给前台
* @param noteId
* @return
*/
List<Privilige> getAllPriviliges(Integer noteId);

}


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.seehope.dao.PriviligeDao;
import net.seehope.po.Privilige;
import net.seehope.po.Role;
import net.seehope.po.Systemoper;
import net.seehope.service.PrivilegeService;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class PrivilegeServiceImpl implements PrivilegeService {

@Resource
private SessionFactory sessionFactory;
@Resource
private PriviligeDao priviligeDao;

public Session getSession(){
return sessionFactory.getCurrentSession();
}

@SuppressWarnings("unchecked")
@Override
public List getAllPriviliges(Integer noteId) {
List<Privilige> topList =
(List<Privilige>) getSession()
.createQuery("From Privilige p where p.parent IS NULL").list();
//存放返回的数据集
List<Map> list = new ArrayList<Map>();
Map map = null;
if(noteId == 0){//首次加载树
//遍历所有的根节点
for (Privilige privilige : topList) {
map = new HashMap();
map.put("id", privilige.getId());
map.put("text", privilige.getText());
map.put("leaf", privilige.isLeaf());
map.put("cls", privilige.getCls());
list.add(map);
}
}else{//非首次加载树
List<Privilige> leafMenu = getMenuByParentId(noteId);//根据父节点id获取其下子节点
Map m = null;
//加载子节点
for (Privilige leafPri : leafMenu) {
m = new HashMap();
m.put("id", leafPri.getId());
m.put("text", leafPri.getText());
m.put("leaf", leafPri.isLeaf());
m.put("cls", leafPri.getCls());
m.put("url", leafPri.getUrl());
list.add(m);
}
}
return list;
}

@SuppressWarnings("unchecked")
@Override
public List<Privilige> getMenuByParentId(Integer pid) {
String hql = "FROM Privilige p where p.parent.id = ?";
List<Privilige> list = getSession().createQuery(hql)
.setParameter(0, pid).list();
return list;
}

@Override
public boolean hasPermission(Systemoper sysOper, Integer menuId) {
//拿到操作员的所有角色
for(Role role : sysOper.getSysrole()){
//拿到角色的所有权限
for(Privilige pri : role.getPriviliges()){
if(menuId.equals(pri.getId())){
return true;
}
}
}
return false;
}

@Override
public boolean hasPermission(Role role, Integer menuId) {
if(role.getPriviliges() != null && role.getPriviliges().size()>0){
for(Privilige pri : role.getPriviliges()){
if(menuId.equals(pri.getId())){
return true;
}
}
}
return false;
}
}

五、设计springMVC的控制类

import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import net.seehope.po.Privilige;
import net.seehope.service.PrivilegeService;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* 操作权限的action
* @author 毛健宇
* 创建日期: 2014-11-3 下午9:34:50
* @version 1.0.0
*/
@Controller
@RequestMapping("Menu")
public class PrivilegeAction {
/**
* Logger for this class
*/
private static final Logger logger = Logger.getLogger(PrivilegeAction.class);

@Resource
private PrivilegeService privilegeServiceImpl;

@RequestMapping(value="showAllMenu")
public @ResponseBody List getTopPrivileges(HttpServletRequest request){
//获得父节点的id
int nid = Integer.valueOf(request.getParameter("nodeId"));
//获取所有权限
List<Privilige> Pris = privilegeServiceImpl.getAllPriviliges(nid);
return Pris;
}
}


这样springMVC就能以json的形式来返回权限菜单数据,前台的extjs就能解析到并加载。
实现的效果如下,当点击父菜单时,会将节点id传到后台再从后台加载数据回来。



注意从springMVC返回json数据时需要用到两个jar包:

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