html框架中的动态权限树(Struts-Menu实现)

来源:互联网 发布:win10 映射网络盘符 编辑:程序博客网 时间:2024/06/05 06:41
 

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" onsubmit="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>

原创粉丝点击