一、简介
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
冰封的爱 阅读(249)
评论(0) 编辑 收藏 所属分类:
J2EE