html框架中的動態權限樹(Struts-Menu實現)

原帖;http://blog.csdn.net/chxzly1981/article/details/1755399

 

1、簡介
  Struts-Menu是一組從基於XML的配置文件中生成多種樣式的菜單的JSP Tags,並且可以結合API開發通過數據庫生成的動態菜單。Struts-Menu支持國際化和多種權限控制。

  以下示例使用了SSH框架、同時對於DAO層使用了Serviece封裝,其配置由於文件過長未給出,而且可以使用JDBC代替

2、運行環境
  Windows xp Professional
  JDK 1.6.0
  Eclipse 5.1.0GA
  Tomcat 6.0.10

  Struts 1.2
  Commons-Lang 2
  Commons-Collections 3.1
  Struts-Menu 2.4.3
  MySQL 5.0.22

3、安裝與配置

1:web.xml,內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <welcome-file-list>
   <welcome-file>logon.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>

      <param-value>
       /WEB-INF/struts-config.xml,
       /WEB-INF/struts-outdepartment.xml,
        /WEB-INF/struts-config/enterprise.xml,
        /WEB-INF/struts-config/inCompany.xml
      </param-value>

    </init-param>
    <init-param>
      <param-name>debug</param-name>
      <param-value>3</param-value>
    </init-param>
    <init-param>
      <param-name>detail</param-name>
      <param-value>3</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
  </servlet>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>ProjectIdCheck</servlet-name>
    <servlet-class>com.founder.servlet.ProjectIdCheck</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ProjectIdCheck</servlet-name>
    <url-pattern>/projectIdCheck</url-pattern>
  </servlet-mapping>

  <filter>
   <filter-name>filter</filter-name>
   <filter-class>com.founder.filter.Filter</filter-class>
  </filter>
  <filter-mapping>
   <filter-name>filter</filter-name>
   <url-pattern>/*</url-pattern>
  </filter-mapping>
 
</web-app>

  2:struts-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
  <data-sources />

  <form-beans >

    <!-- 登陸 -->
   <form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm">
     <form-property name="password" type="java.lang.String" />
     <form-property name="empId" type="java.lang.String" />
    </form-bean>
  </form-beans>

 

  <global-exceptions />
  <global-forwards />
  <action-mappings >
   

  <!-- 登陸 -->
    <action
    attribute="loginForm"
     input="/logon.jsp"
    name="loginForm"
    path="/login"
     scope="request"
     type="com.founder.action.power.LoginAction" >      
     <forward name="failure" path="/logon.jsp" />
     <forward name="success" path="/showPower.do?method=showPower" redirect="true"/>      
    </action>
   <action
    parameter="method"
    path="/showPower"
    type="com.founder.action.power.ShowPowerAction" >
      <forward name="success" path="/index.jsp" redirect="true"/>      
       <forward name="failure" path="/logon.jsp" />
   </action>

  </action-mappings>


  <!-- <controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/>-->
  <message-resources parameter="com.founder.res.ApplicationResources" />
  <plug-in className="net.sf.navigator.menu.MenuPlugIn">
    <set-property property="menuConfig" value="/WEB-INF/menu-config.xml" />
  </plug-in>
</struts-config>

 

  3:解壓縮struts-menu,將壓縮包中的jar釋放到lib目錄中,將壓縮包中的tld釋放到web/WEB -INF目錄中,解壓縮commons-lang,將jar解壓縮到lib目錄中,注意,在 Struts-Menu的文檔中沒有看到需要這個包,但是沒有這個包卻無法成功加載。在web/WEB-INF目錄中新建menu- config.xml,內容如下:
<?xml version="1.0" encoding="UTF-8" ?>

<MenuConfig>

  <Displayers>
    <Displayer   name="DropDown"
                 type="net.sf.navigator.displayer.DropDownMenuDisplayer"/>
    <Displayer   name="Simple"
                 type="net.sf.navigator.displayer.SimpleMenuDisplayer"/>
    <Displayer   name="CoolMenu"
                 type="net.sf.navigator.displayer.CoolMenuDisplayer"/>
    <Displayer   name="CoolMenu4"
                 type="net.sf.navigator.displayer.CoolMenuDisplayer4"/>
    <Displayer   name="MenuForm"
                 type="net.sf.navigator.example.PermissionsFormMenuDisplayer"/>
    <Displayer   name="ListMenu"
                 type="net.sf.navigator.displayer.ListMenuDisplayer"/>
    <Displayer   name="TabbedMenu"
                 type="net.sf.navigator.displayer.TabbedMenuDisplayer"/>
    <Displayer   name="Velocity"
                 type="net.sf.navigator.displayer.VelocityMenuDisplayer"/>
  </Displayers>

  <Menus>
    <Menu  name="DoorSite"  title="DoorSite"  description="Some famous doorsite" width="50">
       <Item   name="Yahoo"   title="Yahoo">
           <Item   name="YahooIndex"   title="Yahoo Index"   location="
http://www.yahoo.com.cn"/>
           <Item   name="YahooMail"    title="Yahoo Mail"    location="
http://cn.mail.yahoo.com"/>
       </Item>
       <Item    name="Sohu"  title="Sohu"   location="
http://www.sohu.com"/>
       <Item    name="Sina"  title="Sina"   location="
http://www.sina.com.cn"/>
    </Menu>
  </Menus>

</MenuConfig>

  4:將第四步的示例程序中的struts-menu應用目錄下的images、scripts、styles三個目錄中的內容複製到web目錄下

  5:你的目錄結構應該類似如下:
    %PROJECT_HOME%/classes
    %PROJECT_HOME%/lib
    %PROJECT_HOME%/lib/antlr.jar
    %PROJECT_HOME%/lib/commons-beanutils.jar
    %PROJECT_HOME%/lib/commons-digester.jar
    %PROJECT_HOME%/lib/commons-fileupload.jar
    %PROJECT_HOME%/lib/commons-lang-2.1.jar
    %PROJECT_HOME%/lib/commons-logging.jar
    %PROJECT_HOME%/lib/commons-validator.jar
    %PROJECT_HOME%/lib/jakarta-oro.jar
    %PROJECT_HOME%/lib/jstl-1.0.6.jar
    %PROJECT_HOME%/lib/standard-1.0.6.jar
    %PROJECT_HOME%/lib/struts.jar
    %PROJECT_HOME%/lib/struts-menu-2.3.jar
    %PROJECT_HOME%/src
    %PROJECT_HOME%/src/log4j.properties
    %PROJECT_HOME%/src/application.properties
    %PROJECT_HOME%/src/application_zh_CN.properties
    %PROJECT_HOME%/web
  %PROJECT_HOME%/web/images/...
   %PROJECT_HOME%/web/scripts/...
   %PROJECT_HOME%/web/styles/...
    %PROJECT_HOME%/web/WEB-INF
    %PROJECT_HOME%/web/WEB-INF/menu-config.xml
    %PROJECT_HOME%/web/WEB-INF/struts-bean.tld
    %PROJECT_HOME%/web/WEB-INF/struts-config.xml
    %PROJECT_HOME%/web/WEB-INF/struts-html.tld
    %PROJECT_HOME%/web/WEB-INF/struts-logic.tld
    %PROJECT_HOME%/web/WEB-INF/struts-menu.tld
    %PROJECT_HOME%/web/WEB-INF/struts-menu-el.tld
    %PROJECT_HOME%/web/WEB-INF/struts-nested.tld
    %PROJECT_HOME%/web/WEB-INF/struts-tiles.tld
    %PROJECT_HOME%/web/WEB-INF/web.xml

4、實戰Struts-Menu
  
 1:新建數據myexamples:
CREATE DATABASE myexamples
  > 新建數據庫表menu_item:
CREATE TABLE menu_item (
   id BIGINT not null,
   parent_name VARCHAR(30),
   name VARCHAR(30),
   title VARCHAR(30),
   titleCN VARCHAR(30),
   description VARCHAR(50),
   location VARCHAR(255),
   target VARCHAR(10),
   onclick VARCHAR(100),
   onmouseover VARCHAR(100),
   onmouseout VARCHAR(100),
   image VARCHAR(50),
   altImage VARCHAR(30),
   tooltip VARCHAR(100),
   roles VARCHAR(100),
   page VARCHAR(255),
   width VARCHAR(5),
   height VARCHAR(5),
   forward VARCHAR(50),
   action VARCHAR(50),
   primary key (id)
)
  > 插入測試數據:
INSERT INTO menu_item
    (id, parent_name, name, title, titleCN, location)
VALUES
    (1,null,'DatabaseMenu','Database Menu','數據庫動態菜單',null),
    (2,'DatabaseMenu','Yahoo','Yahoo Mail','雅虎郵件','http://mail.yahoo.com'),
    (3,'DatabaseMenu','JavaBlogs','JavaBlogs','Java博客','http://javablogs.com'),
    (4,null,'StandaloneMenu','Standalone Menu','獨立的菜單','http://www.sohu.com')
  > 將數據庫驅動程序放到lib目錄中,並加入到Build Path,如MySQL的數據庫驅動mysql-connector-java-5.0.6-bin.jar

  2:

新建一個Struts的Action,代碼如下:

/*
 * Generated by MyEclipse Struts
 * Template path: templates/java/JavaClass.vtl
 */
package com.founder.action.power;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;

import com.founder.beans.Department;
import com.founder.beans.Employee;
import com.founder.beans.Part;
import com.founder.beans.Users;
import com.founder.serviece.ICommonServiece;
import com.founder.serviece.IUprServiece;
import com.founder.serviece.impl.CommonServiece;
import com.founder.util.Systool;

/**
 * @author chx
 *
 */
public class LoginAction extends Action
{
 /**
  * Method execute
  * @param mapping
  * @param form
  * @param request
  * @param response
  * @return ActionForward
  */
 public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
 {

 //這裏使用的框架爲SSH+Serviece接口,可以用JDBC替代
  //通過配置的工廠獲取IUprServiece接口實例
  IUprServiece iserviece = (IUprServiece) Systool.getBean("uprServiece");
  //獲取請求中傳遞參數的表單實例
  DynaActionForm login = (DynaActionForm) form;
  //獲取登陸員工編號
  String empId = login.getString("empId");
  //通過IUprServiece實例獲取登陸員工用戶信息
  Users user = iserviece.getUser(empId);
  //如果用戶存在
  if(user != null)
  {
   //如果用戶輸入不得密碼正確
   if(user.getUserPassword().equals(login.getString("password")))
   {
    //獲取登陸用戶的角色信息
    List<Part> list = iserviece.getPartList(empId);
    //通過配置的工廠獲取ICommonServiece接口實例
    ICommonServiece serviece = (CommonServiece)Systool.getBean("commonServiece");
    //通過CommonServiece實例獲取員工信息
    Employee employee = serviece.getEmployeeById(empId);
    //獲取員工所在部門信息
    Department department = employee.getDepartment();
    //將員工所在的部門信息、員工編號、員工的角色信息放入請求對象
    request.getSession().setAttribute("logindepartment", department);
    request.getSession().setAttribute("loginemid", empId);
    request.getSession().setAttribute("loginpart", list.get(0));
    //登陸成功
    return mapping.findForward("success");
   }
   //如果密碼錯誤,設置出錯提示
   request.setAttribute("message", "密碼錯誤,請確認後再次登陸!");
   //轉回登陸頁面
   return mapping.findForward("failure");
  }
  else
  {
   //如果用戶不存在,設置出錯提示
   request.setAttribute("message", "該員工不存在,請確認後再次登陸!");
   //轉回登陸頁面
   return mapping.findForward("failure");
  }
 }

 
}

 

新建一個Struts的Action,代碼如下:
/*
 * Generated by MyEclipse Struts
 * Template path: templates/java/JavaClass.vtl
 */
package com.founder.action.power;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.navigator.menu.MenuComponent;
import net.sf.navigator.menu.MenuRepository;
import net.sf.navigator.menu.PermissionsAdapter;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import com.founder.beans.Role;
import com.founder.serviece.IUprServiece;
import com.founder.util.Systool;

/**
 * @author chx
 *
 */
public class ShowPowerAction extends DispatchAction
{
 /**
  * 顯示用戶的角色和權限信息
  * Method showPower
  * @param mapping
  * @param form
  * @param request
  * @param response
  * @return ActionForward
  */
 public ActionForward showPower(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
 {
  //通過配置的工廠獲取IUprServiece接口實例
  IUprServiece iserviece = (IUprServiece) Systool.getBean("uprServiece");
  //獲取會話中傳遞的登陸員工編號
  String empId = (String) request.getSession().getAttribute("loginemid");
  //獲取員工的權限信息集合
  List<Role> rolesList = iserviece.getRoleList(empId);
  
  //如果員工無權限,返回登陸頁面
  if (rolesList.size()<0)
  {
   request.setAttribute("message", "您沒有權限,請與系統管理員聯繫!");
   return mapping.findForward("failure");
  }
  //創建權限菜單結構
  this.buildMenuRepository(rolesList, request);
  //構造菜單權限
     this.buildMenuPermissions(request);
     //轉向主頁面
  return mapping.findForward("success");
 }

    /**
     * 創建權限菜單結構
     * @param rolesList
     * @param request
     */
 private void buildMenuRepository(List<Role> rolesList, HttpServletRequest request)
 {
  //獲取一個菜單結構
  MenuRepository repository = new MenuRepository();
        // Get the repository from the application scope - and copy the
        // DisplayerMappings from it.
        MenuRepository defaultRepository = (MenuRepository) request.getSession().getServletContext().getAttribute(MenuRepository.MENU_REPOSITORY_KEY);
        repository.setDisplayers(defaultRepository.getDisplayers());
        //遍歷員工權限
  for (int i=0; i < rolesList.size(); i++)
   {
   //實例化一個菜單節點對象
    MenuComponent mc = new MenuComponent();
    //獲取權限集合中的權限
    Role role = rolesList.get(i);
    String name = role.getRoleCode();
    //將權限名賦予菜單節點
            mc.setName(name);
            //獲取權限的父權限
            String parent = (String) role.getParentCode();
//          System.out.println(name + ", parent is: " + parent);
            //如果權限的父權限存在
            if (parent != null && parent != "")
            {
             //得到節點的父節點實例
                MenuComponent parentMenu = repository.getMenu(parent);
                //如果父節點存在
                if (parentMenu == null)
                {
//                  System.out.println("parentMenu '" + parent + "' doesn't exist!");
                    // create a temporary parentMenu
                 //將父權限設置爲父節點
                    parentMenu = new MenuComponent();
                    parentMenu.setName(parent);
                    repository.addMenu(parentMenu);
                }
                mc.setParent(parentMenu);
            }
            //設置節點屬性
            String title = role.getRoleName();
            mc.setTitle(title);
            mc.setLocation(role.getUrl());
            mc.setTarget("main");
            //將節點放入菜單結構中
            repository.addMenu(mc);
  }
  //將菜單結構放入會話對象
   request.getSession().setAttribute("repository", repository);
 }

    /**
     * 構造菜單權限
     * @param request
     */
    private void buildMenuPermissions(HttpServletRequest request)
    {
        PermissionsAdapter permession = new PermissionsAdapter()
        {
            public boolean isAllowed(MenuComponent menu)
            {
                // 名稱等於StandaloneMenu的菜單不顯示
                return !"StandaloneMenu".equalsIgnoreCase(menu.getName());
            }
        };
        request.getSession().setAttribute("PermissionAdapter", permession);
    }

}

  3:新建JSP文件logon.jsp,內容如下:
<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<%@ taglib uri="/WEB-INF/message.tld" prefix="showmsg"%>
 
<html>
  <showmsg:alert message="msg"/>
  <head>
 <title>My JSP 'login.jsp' starting page</title>
 <link href="/FounderOA/styles/styles.css" _fcksavedurl=""/FounderOA/styles/styles.css"" _fcksavedurl=""/FounderOA/styles/styles.css"" rel="stylesheet" type="text/css">
 <script type="text/javascript" src="/FounderOA/js/employee.js"></script>
 <script type="text/javascript">
 function idcheck(obj)
 {
  return nullcheck('員工編號', obj);
 }
 function pwdcheck(obj)
 {
  return nullcheck('您的密碼', obj);
 }
 function check()
 {
  var idObj = document.all.loginForm.empId;
  var pwdObj = document.all.loginForm.password;
  if (idcheck(idObj) && pwdcheck(pwdObj))
  {
   return true;
  }
  return false;
 }
 </script>
  </head>
  <body>
 <form name="loginForm" method="post" action="login.do" οnsubmit="return check();">
   <table width="250" border="1" align="center" cellpadding="5" cellspacing="0">
    <tr>
      <td width="70" align="right">編號:</td>
      <td><input type="text" name="empId" id="empId" width="150"/></td>
    </tr>
    <tr>
      <td align="right">密碼:</td>
      <td><input type="password" name="password" id="password" width="150"/></td>
    </tr>
    <tr>
      <td colspan="2" align="center">
        <input type="submit" name="submit" value="登陸">
        <input type="reset" name="reset" value="取消">
      </td>
    </tr>
   </table>
 </form>
  </body>
</html>

 

新建JSP文件left.jsp,內容如下:

<%@ page contentType="text/html;charset=gb2312" language="java"%>
<%@ taglib uri="/WEB-INF/struts-menu.tld" prefix="menu" %>
<%@ taglib uri="/WEB-INF/struts-menu-el.tld" prefix="menu-el" %>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
 <title>Dynamic, Database-driven Menu</title>
    <link rel="stylesheet" type="text/css" media="all"
        href="/FounderOA/styles/menuExpandable.css" _fcksavedurl=""/FounderOA/styles/menuExpandable.css"" _fcksavedurl=""/FounderOA/styles/menuExpandable.css"" />
    <script type="text/javascript"
        src="/FounderOA/scripts/menuExpandable.js"></script>
    <link rel="stylesheet" type="text/css" media="all"
        href="/FounderOA/styles/xtree.css" />
    <script type="text/javascript"
        src="/FounderOA/scripts/xtree.js"></script>
    <link rel="stylesheet" type="text/css" media="all"
        href="/FounderOA/styles/global.css" />
</head>
<body>
    <div class="dynamicMenu tree">
       
     <menu:useMenuDisplayer name="DropDown" repository="repository" permissions="PermissionAdapter">  
      <table width="90%" align="left" cellpadding="0" cellspacing="0">  
     <c:forEach var="menu" items="${repository.topMenus}">  
       <menu-el:displayMenu name="${menu.name}" />  
     </c:forEach>  
     </table>  
    </menu:useMenuDisplayer>
    </div>
</body>
</html>

 

其中框架爲:index.jsp

<%@ page language="java" pageEncoding="gb2312"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <frameset rows="70,*,50">
  <frame name="top" noresize frameborder="0" src="top.jsp">
  <frameset id="Middle" cols="200,*" border="0" frameborder="1" frameSpacing="0">
   <frame frameborder="0" noresize name="left" src="left.jsp">
   <frame frameborder="0" noresize name="main" src="main.jsp">
  </frameset>
  <frame name="bottom" noresize frameborder="0" src="buttom.jsp">
 </frameset>
</html>

 

發佈了97 篇原創文章 · 獲贊 3 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章