posts - 14,  comments - 37,  trackbacks - 0
一、简介
  Struts-Menu是一组从基于XML的配置文件中生成多种样式的菜单的JSP Tags,并且可以结合API开发通过数据库生成的动态菜单。Struts-Menu支持国际化和多种权限控制。

二、运行环境
  Windows 2000 Professional
  JDK 1.4.2_03
  Eclipse 3.1
  Tomcat 5.0.28
  Tomcat Plugin 3.1Beta
  Struts 1.2.7
  Commons-Lang 2.1
  Commons-Collections 3.1
  Struts-Menu 2.3
  MySQL 4.1.10a-nt

三、下载与安装
  1:从
http://java.sun.com下载J2SDK,当前1.4.x系列的最新版本为1.4.2_08
  2:从
http://www.eclipse.org下载Eclipse,当前最新版本为3.1正式版
  3:从
http://jakarta.apache.org/tomcat下载Tomcat,当前5.x系列的最新版本为5.0.28
  4:从
http://www.sysdeo.com/eclipse/tomcatplugin下载Eclipse的Tomcat插件,对应Eclipse3.1x的最新版本为3.1Beta
  5:从
http://struts.apache.org下载Struts,当前最新版本为1.2.7
  6:从
http://jakarta.apache.org/commons/下载Commons-Lang,当前最新版本为2.1,下载Commons-Collections,当前最新版本为3.1
  7:从
http://struts-menu.sourceforge.net下载Struts Menu,当前最新版本为2.3
  8:从
http://www.mysql.com下载MySQL数据库,4.x系列的最新版本是4.1.12a
  9:MySQL、JDK、Eclipse、Tomcat和TomcatPlugin的安装及配置请参考相关资料

四、运行示例程序
  1:安装好Tomcat后,解压缩struts-menu-2.3.zip,将struts-menu.war释放到Tomcat安装目录下的webapps下,运行Tomcat
  2:在地址栏输入
http://localhost:8080/struts-menu

五、安装与配置
  1:在Eclipse中新建Tomcat项目,Context为/mymenu,Subdirectory为/web
  2:在项目目录下面新建lib目录和web目录及WEB-INF,在web/WEB-INF目录下新建web.xml,内容如下:

 

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd"
>

<web-app>
  
<display-name>My Example Application -- Vinton Lee</display-name>
      
  
<!-- ============= The Struts ActionServlet Configuration ============= -->
  
<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</param-value>
    
</init-param>
    
<load-on-startup>1</load-on-startup>
  
</servlet>
  
<!-- ================================================================== -->
    
  
<!-- ============= The Struts Action Servlet Mapping ================== -->
  
<servlet-mapping>
    
<servlet-name>action</servlet-name>
    
<url-pattern>*.do</url-pattern>
  
</servlet-mapping>
  
<!-- ================================================================== -->
  
  
<!-- The Welcome File List -->
  
<welcome-file-list>
    
<welcome-file>index.jsp</welcome-file>
  
</welcome-file-list>

  
<!-- =============== The Struts Taglib Definition ===================== -->
  
<taglib>
    
<taglib-uri>struts-bean</taglib-uri>
    
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
  
</taglib>
  
<taglib>
    
<taglib-uri>struts-html</taglib-uri>
    
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
  
</taglib>
  
<taglib>
    
<taglib-uri>struts-logic</taglib-uri>
    
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
  
</taglib>
  
<taglib>
    
<taglib-uri>struts-nested</taglib-uri>
    
<taglib-location>/WEB-INF/struts-nested.tld</taglib-location>
  
</taglib>
  
<taglib>
    
<taglib-uri>struts-tiles</taglib-uri>
    
<taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>
  
</taglib>
  
<!-- ================================================================== -->
  
  
<!-- ============= The Struts-Menu Taglib Definition ================== -->
  
<taglib>
    
<taglib-uri>struts-menu</taglib-uri>
    
<taglib-location>/WEB-INF/struts-menu.tld</taglib-location>
  
</taglib>
  
<!-- ================================================================== -->
</web-app>

 

  3:解压缩struts-1.2.7.zip,将压缩包中的lib目录下所有的8个jar释放到lib目录中,将5个tld文件释放到web\WEB-INF目录中,在web\WEB-INF目录中新建struts-config.xml,内容如下:

 

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!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 Source Configuration =============================== -->
    
<data-sources />

    
<!-- ========== Form Bean Definitions =================================== -->
    
<form-beans />

    
<!-- ========== Global Exception Definitions ============================ -->
    
<global-exceptions />

    
<!-- ========== Global Forward Definitions ============================== -->
    
<global-forwards />

    
<!-- ========== Action Mapping Definitions ============================== -->
    
<action-mappings />

    
<!-- ========== Controller Configuration ================================ -->

    
<!-- ========== Message Resources Definitions =========================== -->
    
<message-resources parameter="application" />

    
<!-- ========== Plug Ins Configuration ================================== -->
    
<plug-in className="net.sf.navigator.menu.MenuPlugIn">
      
<set-property property="menuConfig" value="/WEB-INF/menu-config.xml"/>
    
</plug-in>

</struts-config>

 

  4:解压缩struts-menu-2.3.zip,将压缩包中的jstl-1.0.6.jar、standard-1.0.6.jar、struts-menu-2.3.jar释放到lib目录中,将压缩包中的struts-menu.tld、struts-menu-el.tld释放到web\WEB-INF目录中,解压缩commons-lang-2.1.zip,将commons-lang-2.1.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>

 

  5:将第四步的示例程序中的struts-menu应用目录下的images、scripts、styles三个目录中的内容复制到web目录下

  6:你的目录结构应该类似如下:
   

%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

 

六、实战Struts-Menu
  1:使用配置文件实现静态菜单
  新建JSP文件web/static-menu.jsp,内容如下:

<%@ page contentType="text/html; charset=GBK" %>
<%@ taglib uri="struts-menu" prefix="menu" %>

<menu:useMenuDisplayer name="ListMenu" 
    bundle
="org.apache.struts.action.MESSAGE">
    
<menu:displayMenu name="DoorSite"/>
</menu:useMenuDisplayer>

  运行Tomcat,在IE地址栏输入http://localhost:8080/mymenu/static-menu.jsp查看

  2:实现中文化
  > 在src\application_zh_CN.properties中增加下面的内容,Unicode可以通过JDK自带的native2ascii工具得到:

#门户网站
menu.DoorSite
=\u95e8\u6237\u7f51\u7ad9
#雅虎
menu.Yahoo
=\u96c5\u864e
#雅虎首页
menu.YahooIndex
=\u96c5\u864e\u9996\u9875
#雅虎邮件
menu.YahooMail
=\u96c5\u864e\u90ae\u4ef6
#搜狐
menu.Sohu
=\u641c\u72d0
#新浪
menu.Sina
=\u65b0\u6d6a


  > 在src\application.properties中增加下面的内容:

#门户网站
menu.DoorSite
=DoorSite
#雅虎
menu.Yahoo
=Yahoo
#雅虎首页
menu.YahooIndex
=Yahoo Index
#雅虎邮件
menu.YahooMail
=Yahoo Mail
#搜狐
menu.Sohu
=Sohu
#新浪
menu.Sina
=Sina


  > 修改menu-config.xml文件<Menus></Menus>部分:

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


  重起Tomcat,在IE地址栏输入
http://localhost:8080/mymenu/static-menu.jsp查看

  3:结合数据库实现动态菜单
  > 新建数据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-3.1.8-bin.jar,解压缩commons-collections-3.1.zip,将commons-collections-3.1.jar释放到lib目录,并加入Build Path
  > 新建一个Struts的Action,代码如下:

  1package cn.appex.menu;
  2
  3import java.io.UnsupportedEncodingException;
  4import java.sql.Connection;
  5import java.sql.DriverManager;
  6import java.sql.PreparedStatement;
  7import java.sql.ResultSet;
  8import java.sql.SQLException;
  9import java.util.ArrayList;
 10import java.util.HashMap;
 11import java.util.ListResourceBundle;
 12import java.util.Map;
 13
 14import com.mysql.jdbc.Driver;
 15
 16import javax.servlet.http.HttpServletRequest;
 17import javax.servlet.http.HttpServletResponse;
 18import javax.servlet.http.HttpSession;
 19
 20import net.sf.navigator.menu.MenuComponent;
 21import net.sf.navigator.menu.MenuRepository;
 22import net.sf.navigator.menu.PermissionsAdapter;
 23
 24import org.apache.struts.action.Action;
 25import org.apache.struts.action.ActionForm;
 26import org.apache.struts.action.ActionForward;
 27import org.apache.struts.action.ActionMapping;
 28
 29public class MenuAction extends Action {
 30    public ActionForward execute(ActionMapping mapping, ActionForm form,
 31            HttpServletRequest request, HttpServletResponse response)
 32            throws Exception {
 33        buildMenuRepository(request);
 34        buildMenuResourceBundle(request);
 35        buildMenuPermissions(request);
 36        return (mapping.findForward("success"));
 37    }

 38
 39    /**
 40     * 创建菜单数据结构
 41     * 
 42     * @param request
 43     */

 44    private void buildMenuRepository(HttpServletRequest request) {
 45        MenuRepository repository = new MenuRepository();
 46        // Get the repository from the application scope - and copy the
 47        // DisplayerMappings from it.
 48        MenuRepository defaultRepository = (MenuRepository) request
 49                .getSession().getServletContext().getAttribute(
 50                        MenuRepository.MENU_REPOSITORY_KEY);
 51        repository.setDisplayers(defaultRepository.getDisplayers());
 52
 53        Map[] menus = getMenuComponents();
 54        for (int i=0; i < menus.length; i++{
 55            MenuComponent mc = new MenuComponent();
 56            Map row = menus[i];
 57            String name = (String) row.get("name");
 58            mc.setName(name);
 59            String parent = (String) row.get("parent_name");
 60            System.out.println(name + ", parent is: " + parent);
 61            if (parent != null{
 62                MenuComponent parentMenu = repository.getMenu(parent);
 63                if (parentMenu == null{
 64                    System.out.println("parentMenu '" + parent + "' doesn't exist!");
 65                    // create a temporary parentMenu
 66                    parentMenu = new MenuComponent();
 67                    parentMenu.setName(parent);
 68                    repository.addMenu(parentMenu);
 69                }

 70
 71                mc.setParent(parentMenu);
 72            }

 73            String title = (String) row.get("title");
 74            mc.setTitle(title);
 75            String location = (String) row.get("location");
 76            mc.setLocation(location);
 77            String description = (String) row.get("description");
 78            mc.setDescription(description);
 79            repository.addMenu(mc);
 80        }

 81        
 82        request.setAttribute("examplesRepository", repository);
 83    }

 84
 85    /**
 86     * 从数据库中读取菜单配置信息
 87     * 
 88     * @return
 89     */

 90    private Map[] getMenuComponents() {
 91        ArrayList list = new ArrayList();
 92        Connection conn = null;
 93        PreparedStatement pstmt = null;
 94        ResultSet rest = null;
 95        String sql = "select name,parent_name,title,location,description from menu_item order by id";
 96        try {
 97            Class.forName("com.mysql.jdbc.Driver").newInstance();
 98            conn = DriverManager.getConnection("jdbc:mysql://localhost/myexamples?user=root&password=mywangya&useUnicode=true&characterEncoding=UTF-8");
 99            pstmt = conn.prepareStatement(sql);
100            rest = pstmt.executeQuery();
101            while (rest.next()) {
102                int i = 1;
103                HashMap map = new HashMap();
104                map.put("name", rest.getString(i++));
105                map.put("parent_name", rest.getString(i++));
106                map.put("title", rest.getString(i++));
107                map.put("location", rest.getString(i++));
108                map.put("description", rest.getString(i++));
109                list.add(map);
110            }

111        }
 catch (SQLException ex) {
112            ex.printStackTrace();
113        }
 catch (InstantiationException e) {
114            e.printStackTrace();
115        }
 catch (IllegalAccessException e) {
116            e.printStackTrace();
117        }
 catch (ClassNotFoundException e) {
118            e.printStackTrace();
119        }
 finally {
120            try {
121                if (null!=rest) rest.close();
122                if (null!=pstmt) pstmt.close();
123                if (null!=conn) conn.close();
124            }
 catch (SQLException e) {
125                e.printStackTrace();
126            }

127        }

128        
129        return (Map[]) list.toArray(new HashMap[0]);
130    }

131    
132    /**
133     * 构造菜单权限
134     * 
135     * @param request
136     */

137    private void buildMenuPermissions(HttpServletRequest request) {
138        PermissionsAdapter permession = new PermissionsAdapter() {
139            public boolean isAllowed(MenuComponent menu) {
140                // 名称等于StandaloneMenu的菜单不显示
141                return !"StandaloneMenu".equalsIgnoreCase(menu.getName());
142            }

143        }
;
144        request.setAttribute("examplesPermession", permession);
145    }

146
147    /**
148     * 构造菜单显示标题
149     * 
150     * @param request
151     */

152    private void buildMenuResourceBundle(HttpServletRequest request) {
153        MenuResourceBundle resourceBundle = new MenuResourceBundle();
154        request.setAttribute("examplesBundle", resourceBundle);
155    }

156    
157    /**
158     * MenuResourceBundle树状菜单国际语言显示
159     * 
160     * @author wenbin.zhang
161     *  
162     */

163    class MenuResourceBundle extends ListResourceBundle {
164        private ArrayList list = new ArrayList();
165
166        public MenuResourceBundle() {
167            Connection conn = null;
168            PreparedStatement pstmt = null;
169            ResultSet rest = null;
170            String sql = "select title,titleCN from menu_item order by id";
171            try {
172                Class.forName("com.mysql.jdbc.Driver").newInstance();
173                conn = DriverManager.getConnection("jdbc:mysql://localhost/myexamples?user=root&password=mywangya&useUnicode=true&characterEncoding=UTF-8");
174                pstmt = conn.prepareStatement(sql);
175                rest = pstmt.executeQuery();
176                while (rest.next()) {
177                    int i = 1;
178                    String[] message = new String[2];
179                    message[0= rest.getString(i++);
180                    try {
181                        message[1= new String(rest.getString(i++).getBytes("latin1"), "gbk");
182                    }
 catch (UnsupportedEncodingException e) {
183                        e.printStackTrace();
184                    }

185                    if (message[0!= null && message[1!= null{
186                        list.add(message);
187                    }

188                }

189            }
 catch (SQLException ex) {
190                ex.printStackTrace();
191            }
 catch (InstantiationException e) {
192                e.printStackTrace();
193            }
 catch (IllegalAccessException e) {
194                e.printStackTrace();
195            }
 catch (ClassNotFoundException e) {
196                e.printStackTrace();
197            }
 finally {
198                try {
199                    if (null!=rest) rest.close();
200                    if (null!=pstmt) pstmt.close();
201                    if (null!=conn) conn.close();
202                }
 catch (SQLException e) {
203                    e.printStackTrace();
204                }

205            }

206
207        }

208
209        public Object[][] getContents() {
210            return (String[][]) list.toArray(new String[0][0]);
211        }

212    }

213}

214
215  
216


 >将struts-config.xml文件的<action-mappings />部分修改为:

<action-mappings>
  
<action path="/menuAction" type="cn.appex.menu.MenuAction" >
    
<forward name="success" path="/struts-menu/dynamic-menu.jsp" />
  
</action>
</action-mappings>


  > 新建JSP文件web/dynamic-menu.jsp,内容如下:

<%@ page contentType="text/html; charset=GBK" %>
<%@ taglib uri="struts-menu" prefix="menu" %>

 

没有使用Bundle和权限控制:

<menu:useMenuDisplayer name="ListMenu" repository="examplesRepository">
    
<menu:displayMenu name="DatabaseMenu"/>
    
<menu:displayMenu name="StandaloneMenu"/>
</menu:useMenuDisplayer>

 

使用Bundle, 没有使用权限控制:

<menu:useMenuDisplayer name="ListMenu" bundle="examplesBundle" repository="examplesRepository">
    
<menu:displayMenu name="DatabaseMenu"/>
    
<menu:displayMenu name="StandaloneMenu"/>
</menu:useMenuDisplayer>

 

使用Bundle和权限控制:

<menu:useMenuDisplayer name="ListMenu" permissions="examplesPermession"  bundle="examplesBundle" repository="examplesRepository">
    
<menu:displayMenu name="DatabaseMenu"/>
    
<menu:displayMenu name="StandaloneMenu"/>
</menu:useMenuDisplayer>


  重起Tomcat,在地址栏输入
http://localhost:8080/mymenu/menuAction.do

七、关于Struts-Menu配置文件和API的使用方法,请参考附录中的官方网站


附:
Struts-Menu官方网站:
http://struts-menu.sourceforge.net
数据库驱动的动态菜单:http://demo.raibledesigns.com/struts-menu/dynamicMenu.jsp

posted on 2007-07-11 10:19 冰封的爱 阅读(238) 评论(0)  编辑  收藏 所属分类: J2EE

只有注册用户登录后才能发表评论。


网站导航:
 
<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(3)

随笔档案

文章分类

文章档案

相册

搜索

  •  

最新评论

阅读排行榜

评论排行榜