最近刚刚完成个项目,由于项目简单,所以领导决定功能菜单不存入到数据库中,只要写死就可以了,可是个人觉得这么做太不灵活,所以思考了一下,决定彩用这种通过XML来配置菜单的方式。只要更改menu.xml文件就可以动态改变菜单的结构。目前只实现了二级菜单的动态变化。这个功能需要以下文件,MenuVO.java这是菜单的传值对象,MenuChildVO.java这是子菜单的传值对象.Menu.xml这是配置文件,MenuList.java这是读取配置文件的类。最后写menu.jsp在此JSP里通过javascript来实现菜单树形结构。
通过这个菜单功能的实现,我觉得以后在设计程序时,可以适量考虑数据的存储方式,是不是用XML+数据库更好些。比如一些比较稳定的数据,记录又不多的情况可以考虑彩用XML的格式来存放。这样可以省去操作数据库的麻烦,也减少了读取数据库的时间。对数据的操作也不难,只要更改配置文件就可以了,很适用的。
========================================================
菜单对象类MenuVO
public class MenuVO {
private String menuid;
private String menuname;
private String menuhref;
private ArrayList child;
public void setMenuid(String menuid){
this.menuid = menuid;
}
public void setMenuname(String menuname){
this.menuname = menuname;
}
public String getMenuid(){
return this.menuid;
}
public String getMenuname(){
return this.menuname;
}
public void setChild(ArrayList child){
this.child = child;
}
public ArrayList getChild(){
return this.child;
}
public void setMenuhref(String menuhref){
this.menuhref = menuhref;
}
public String getMenuhref(){
return this.menuhref;
}
}
================================================
子菜单对象类
public class MenuChildVO {
private String menuhref="";
private String menuname="";
public void setMenuHref(String menuhref){
this.menuhref = menuhref;
}
public void setMenuName(String menuname){
this.menuname = menuname;
}
public String getMenuHref(){
return this.menuhref;
}
public String getMenuName(){
return this.menuname;
}
}
==============================================
menu.xml菜单管理的配置文件,放在WEB-INF下面即可
<?xml version="1.0" encoding="GB2312"?>
<menu>
<items name="菜单一" code="SYSTEMMENU" href="#">
<item href="child11.jsp" name="新增用户角色"/>
<item href="child12.jsp" name="维护用户角色"/>
</items>
<items name="菜单二" code="COMMONMENU" href="#">
<item href="child21.jsp" name="新增普通用户"/>
<item href="child22.do" name="维护普通用户"/>
</items>
<items name="菜单三" code="MENUTEST" href="menutest.jsp"/>
</menu>
=========================================
读取菜单配置文件的类MenuList.java
import java.util.ArrayList;
import sports.vo.MenuVO;
import sports.vo.MenuChildVO;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
public class MenuList {
private static MenuList menulist = null;
private MenuList() {
}
public static MenuList getInstance() {
if (menulist == null) {
menulist = new MenuList();
}
return menulist;
}
public ArrayList getMenu(HttpServletRequest request) {
ArrayList menu = new ArrayList();
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File(request.getRealPath("/") + "WEB-INF" + File.separatorChar + "menu.xml"));
NodeList links = doc.getElementsByTagName("items");
for (int i = 0; i < links.getLength(); i++) {
Element link = (Element) links.item(i);
MenuVO vo = new MenuVO();
vo.setMenuname(link.getAttributeNode("name").getNodeValue());
vo.setMenuid(link.getAttributeNode("code").getNodeValue());
vo.setMenuhref(link.getAttributeNode("href").getNodeValue());
NodeList childs = link.getElementsByTagName("item");
ArrayList almenu = new ArrayList();
for(int j=0;j<childs.getLength();j++){
Element child = (Element)childs.item(j);
MenuChildVO mcvo = new MenuChildVO();
mcvo.setMenuHref(child.getAttributeNode("href").getNodeValue());
mcvo.setMenuName(child.getAttributeNode("name").getNodeValue());
almenu.add(mcvo);
}
vo.setChild(almenu);
menu.add(vo);
}
}
catch (Exception e) {
}
return menu;
}
}
======================================================
menu.jsp菜单文件
<html>
<head>
<script type="text/jscript">
scores = new Array(20);
var numTotal=0;
NS4 = (document.layers) ? 1 : 0;
IE4 = (document.all) ? 1 : 0;
ver4 = (NS4 || IE4) ? 1 : 0;
if (ver4) {
with (document) {
write("<STYLE TYPE='text/css'>");
if (NS4) {
write(".parent {position:absolute; visibility:visible}");
write(".child {position:absolute; visibility:visible}");
write(".regular {position:absolute; visibility:visible}")
}
else {
write(".child {display:none}")
}
write("</STYLE>");
}
}
function getIndex(el) {
ind = null;
for (i=0; i<document.layers.length; i++) {
whichEl = document.layers[i];
if (whichEl.id == el) {
ind = i;
break;
}
}
return ind;
}
function arrange() {
nextY = document.layers[firstInd].pageY +document.layers[firstInd].document.height;
for (i=firstInd+1; i<document.layers.length; i++) {
whichEl = document.layers[i];
if (whichEl.visibility != "hide") {
whichEl.pageY = nextY;
nextY += whichEl.document.height;
}
}
}
function initIt(){
if (!ver4) return;
if (NS4) {
for (i=0; i<document.layers.length; i++) {
whichEl = document.layers[i];
if (whichEl.id.indexOf("Child") != -1) whichEl.visibility = "hide";
}
arrange();
}
else {
divColl = document.all.tags("DIV");
for (i=0; i<divColl.length; i++) {
whichEl = divColl(i);
if (whichEl.className == "child") whichEl.style.display = "none";
}
}
}
function expandIt(el) {
if (!ver4) return;
if (IE4) {
whichEl1 = eval(el + "Child");
for(i=1;i<=numTotal;i++){
whichEl = eval(scores[i] + "Child");
if(whichEl!=whichEl1) {
whichEl.style.display = "none";
}
}
whichEl1 = eval(el + "Child");
if (whichEl1.style.display == "none") {
whichEl1.style.display = "block";
}
else {
whichEl1.style.display = "none";
}
}
else {
whichEl = eval("document." + el + "Child");
for(i=1;i<=numTotal;i++){
whichEl = eval("document." + scores[i] + "Child");
if(whichEl!=whichEl1) {
whichEl.visibility = "hide";
}
}
if (whichEl.visibility == "hide") {
whichEl.visibility = "show";
}
else {
whichEl.visibility = "hide";
}
arrange();
}
}
onload = initIt;
</script>
</head>
<body>
<%
String MENUSCRIPT = "";
//取得用户功能项
String function = "SYSTEMMENU,CUMMONMENU,MENUTEST,";
String MENU = "",sMenu="";
Vector vMenu = new Vector();
if(function != null)
vMenu = StringUtils.getVector(function,",");
/*******************************************************************/
//确定菜单项
int menunum = 0;
ArrayList al = MenuList.getInstance().getMenu(request);
//菜单组合
for(int i=0;i<al.size();i++){
MenuVO menuvo = (MenuVO)al.get(i);
if(vMenu.contains(menuvo.getMenuid())){
ArrayList al_child = new ArrayList();
al_child = menuvo.getChild();
menunum++;
System.out.println(menuvo.getMenuname() + menuvo.getMenuhref());
if(!menuvo.getMenuhref().equals("#")){
MENU += "<div id=KB" + menunum + "Parent>"+
" <a href=/"" + menuvo.getMenuhref() + "/" target=/"right/"><img src=/"images/plus.gif/" border=0>" + menuvo.getMenuname() + "</a>"+
"</div>"+
"<div class=child id=KB" + menunum + "Child>";
}else{
MENU += "<div id=KB" + menunum + "Parent>"+
" <a onClick=/"expandIt('KB" + menunum + "');return false/" href=/"" + menuvo.getMenuhref() + "/"><img src=/"images/plus.gif/" border=0>" + menuvo.getMenuname() + "</a>"+
"</div>"+
"<div class=child id=KB" + menunum + "Child>";
}
//子菜单组合
for(int j=0;j<al_child.size();j++){
MenuChildVO mcvo = (MenuChildVO)al_child.get(j);
MENU += " <a href=/"" + mcvo.getMenuHref() + "/" target=/"right/"><img src=/"images/blank.gif/" border=0>" + mcvo.getMenuName() + "</a><br>";
}
MENU += "</div>";
}
//组合菜单数组
sMenu += "scores[" + menunum + "]='KB" + menunum + "';";
}
MENUSCRIPT = "numTotal=" + menunum + ";" + sMenu;
//确定菜单项结束
/*******************************************************************/
%>
<%=MENU%>
<script type="text/jscript"><%=MENUSCRIPT%></script>
</body>