extjs springMVC实现动态树形菜单

最近由于项目需要,做一个树形动态菜单,用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











  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值