<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    海鷗航際

    JAVA站
    posts - 11, comments - 53, trackbacks - 1, articles - 102

    Struts原理與實(shí)踐(8)

    Posted on 2005-03-23 18:00 海天一鷗 閱讀(341) 評(píng)論(0)  編輯  收藏 所屬分類: Struts專題
    在上一篇文章中介紹JavaScript實(shí)現(xiàn)級(jí)聯(lián)下拉菜單的例子,本篇繼續(xù)介紹一個(gè)利用現(xiàn)存的JavaScript代碼配合struts構(gòu)成一個(gè)樹型菜單的例子。

        大家知道,樹型菜單在應(yīng)用中有著十分廣泛的用途。實(shí)現(xiàn)樹型菜單的途徑較多,本文介紹的一種覺得理解起來比較直觀,與上篇文章的方法比較類似:就是將樹型菜單的節(jié)點(diǎn)保存在數(shù)據(jù)庫(kù)表中(當(dāng)然,在實(shí)際項(xiàng)目中,節(jié)點(diǎn)的信息往往并不是放在一個(gè)單一的表中的。比如:在一個(gè)權(quán)限管理系統(tǒng)中,這些信息可能分別放在用戶表、角色表、功能表等表中,只要設(shè)法讓查詢出來的結(jié)果與下面給出的表格的內(nèi)容相似就可以了。只要稍微有些數(shù)據(jù)庫(kù)方面的知識(shí)做到這點(diǎn)并不難,詳細(xì)的實(shí)現(xiàn)細(xì)節(jié)超出了本文的主題,不在此細(xì)說)。通過數(shù)據(jù)訪問對(duì)象將其從數(shù)據(jù)庫(kù)中查出后放在一個(gè)集合對(duì)象中,并將該集合對(duì)象傳遞給客戶端,再用一段現(xiàn)存的JavaScript代碼--dtree(一個(gè)免費(fèi)的JavaScript程序)來操作集合中的數(shù)據(jù)。大方向確定之后,我們就來具體著手來實(shí)現(xiàn)它。

        根據(jù)dtree的要求,我們來建一個(gè)數(shù)據(jù)庫(kù)表來存儲(chǔ)樹的節(jié)點(diǎn)信息,表名為functions,其結(jié)構(gòu)如下:

    id字段:varchar 10 主鍵--節(jié)點(diǎn)標(biāo)識(shí)碼
    pid字段:varchar 10 not null--父節(jié)點(diǎn)標(biāo)識(shí)碼
    name字段:varchar 20 not null
    url字段:varchar 50 not
    null--這個(gè)字段存儲(chǔ)的是點(diǎn)擊該節(jié)點(diǎn)時(shí),要定位的資源(比如一個(gè)頁(yè)面的url),
    為了不使本文的篇幅過長(zhǎng),暫時(shí)不給出相應(yīng)的頁(yè)面,
    您可以隨便輸入一個(gè)字母比如:a,以使本例能夠正常運(yùn)行。
    title字段:varchar 20
    target字段:varchar 10
    icon字段:varchar 20
    iconopen字段:varchar 20
    opened字段:char 1


        在表中輸入如下一些記錄以供后面的實(shí)驗(yàn)用:

    0、-1、我的權(quán)限、javascript: void(0);
    00、0、用戶管理、javascript: void(0);
    0001、00、創(chuàng)建新用戶;
    0002、00、刪除用戶;
    01、0、	文章管理、javascript: void(0);
    0101、01、添加新文章;
    0102、01、修改文章;
    0103、01、刪除文章;


        到此,數(shù)據(jù)庫(kù)方面的準(zhǔn)備工作就告一段落。

        接下來的工作我們?nèi)匀辉谙惹敖榻B的mystruts項(xiàng)目中進(jìn)行。先編寫一個(gè)名為:FunctionsForm的ActionForm,其代碼如下:

    package entity;
    import org.apache.struts.action.*;
    import javax.servlet.http.*;
    
    public class FunctionsForm extends ActionForm {
      private String icon;
      private String iconOpen;
      private String id;
      private String name;
      private String opened;
      private String pid;
      private String target;
      private String title;
      private String url;
      public String getIcon() {
        return icon;
      }
      public void setIcon(String icon) {
        this.icon = icon;
      }
      public String getIconOpen() {
        return iconOpen;
      }
      public void setIconOpen(String iconOpen) {
        this.iconOpen = iconOpen;
      }
      public String getId() {
        return id;
      }
      public void setId(String id) {
        this.id = id;
      }
      public String getName() {
        return name;
      }
      public void setName(String name) {
        this.name = name;
      }
      public String getOpened() {
        return opened;
      }
      public void setOpened(String opened) {
        this.opened = opened;
      }
      public String getPid() {
        return pid;
      }
      public void setPid(String pid) {
        this.pid = pid;
      }
      public String getTarget() {
        return target;
      }
      public void setTarget(String target) {
        this.target = target;
      }
      public String getTitle() {
        return title;
      }
      public void setTitle(String title) {
        this.title = title;
      }
      public String getUrl() {
        return url;
      }
      public void setUrl(String url) {
        this.url = url;
      }
    }


        因?yàn)槲覀兊臉湫凸?jié)點(diǎn)的數(shù)據(jù)都存儲(chǔ)在數(shù)據(jù)庫(kù)表中,接下來,要做一個(gè)數(shù)據(jù)訪問對(duì)象類,名稱為:FunctionsDao.java,其代碼如下:

    package db;
    import java.sql.*;
    import java.util.*;
    import entity.FunctionsForm;
    
    public class FunctionsDao {
      private static Connection con = null;
    
      public FunctionsDao(Connection con) {
        this.con=con;
      }
    
      public static Collection findTree() {
        PreparedStatement ps=null;
        ResultSet rs = null;
        ArrayList list=new ArrayList();
    
        String sql="select * from functions";
    
        try{
          if(con.isClosed()){
            throw new IllegalStateException("error.unexpected");
    
          }
          ps=con.prepareStatement(sql);
    
          rs=ps.executeQuery();
          while(rs.next()){
            FunctionsForm functionsForm=new FunctionsForm();
            functionsForm.setId(rs.getString("id"));
            functionsForm.setPid(rs.getString("pid"));
            functionsForm.setName(rs.getString("name"));
            functionsForm.setUrl(rs.getString("url"));
            functionsForm.setTitle(rs.getString("title"));
            functionsForm.setTarget(rs.getString("target"));
            functionsForm.setIcon(rs.getString("icon"));
            functionsForm.setIconOpen(rs.getString("iconOpen"));
            functionsForm.setOpened(rs.getString("opened"));
            list.add(functionsForm);
    
          }
          return list;
        }
        catch(SQLException e){
            e.printStackTrace();
            throw new RuntimeException("error.unexpected");
        }
        finally{
          try{
            if(ps!=null)
              ps.close();
            if(rs!=null)
              rs.close();
          }catch(SQLException e){
            e.printStackTrace();
            throw new RuntimeException("error.unexpected");
          }
        }
      }
    }


        這里值得注意的是:在以往我們見到的一些顯示樹型菜單的程序,如:一些asp程序中往往簡(jiǎn)單地采用遞歸調(diào)用的方法來查找到樹的各個(gè)節(jié)點(diǎn)。這對(duì)那些樹的深度不確定的場(chǎng)合還是有些用處,但這種處理方法也有一個(gè)致命的弱點(diǎn),那就是反復(fù)地進(jìn)行數(shù)據(jù)庫(kù)查詢,對(duì)一些節(jié)點(diǎn)較多的應(yīng)用,對(duì)應(yīng)用程序性能的影響是非常大的,有時(shí)會(huì)慢得讓人難以接受;而在實(shí)際的應(yīng)用中大多數(shù)情況下樹的深度往往是有限的,如:用于會(huì)計(jì)科目的樹一般最多也在六層以下。又如:用作網(wǎng)頁(yè)功能菜單的情況,網(wǎng)頁(yè)設(shè)計(jì)的原則就有一條是:達(dá)到最終目的地,鼠標(biāo)點(diǎn)擊次數(shù)最好不要多于三次。因此,在實(shí)際設(shè)計(jì)存儲(chǔ)樹型結(jié)構(gòu)的表時(shí)要考慮查詢的效率。對(duì)能確定樹的最大深度的情況下,要設(shè)法盡量?jī)?yōu)化查詢語(yǔ)句,減少查詢次數(shù),以提高應(yīng)用程序的性能同時(shí)減少數(shù)據(jù)庫(kù)的負(fù)荷。

        本例對(duì)應(yīng)的Action的名稱為FunctionsAction,其代碼如下:

    package action;
    
    import entity.*;
    import org.apache.struts.action.*;
    import javax.servlet.http.*;
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Collection;
    import db.FunctionsDao;
    
    public class FunctionsAction extends Action {
      public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm,
      HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) 
      {
        DataSource dataSource;
        Connection cnn=null;
        ActionErrors errors=new ActionErrors();
        try{
          dataSource = getDataSource(httpServletRequest,"A");
          cnn = dataSource.getConnection();
          FunctionsDao functionsDao=new FunctionsDao(cnn);
          Collection col=functionsDao.findTree();
          httpServletRequest.setAttribute("treeList",col);
    
          return actionMapping.findForward("success");
        }
        catch(Throwable e){
          e.printStackTrace();
          //throw new RuntimeException("未能與數(shù)據(jù)庫(kù)連接");
          ActionError error=new ActionError(e.getMessage());
          errors.add(ActionErrors.GLOBAL_ERROR,error);
        }
        finally{
          try{
            if(cnn!=null)
              cnn.close();
          }
          catch(SQLException e){
            throw new RuntimeException(e.getMessage());
          }
        }
        saveErrors(httpServletRequest,errors);
        return actionMapping.findForward("fail");
      }
    }


        在struts-config.xml文件中加入如下內(nèi)容:

    <form-beans>    
        <form-bean name="functionsForm" type="entity.FunctionsForm" />
      </form-beans>
    <action-mappings>
        <action name="functionsForm" path="/functionsAction" scope="request"
    	type="action.FunctionsAction" validate="false" >
    <forward name="success" path="/testDTree.jsp" />
    <forward name="fail" path="/genericError.jsp" />
        </action>
      </action-mappings>


        為了對(duì)應(yīng)配置中的,我們還要提供一個(gè)顯示錯(cuò)誤信息的jsp頁(yè)面,其代碼如下:

    <%@ page contentType="text/html; charset=UTF-8" %>
    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    <html>
    <head>
    <title>
    genericError
    </title>
    <link href="css/mycss.css" rel="stylesheet" type="text/css">
    </head>
    <body bgcolor="#ffffff">
    <html:errors/>
    </body>
    </html>


        下面,我們來看一下我們顯示樹型菜單的頁(yè)面代碼,從配置中可以看出,頁(yè)面的名稱為testDTree.jsp,代碼如下:

    <%@ page contentType="text/html; charset=UTF-8" %>
    <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
    <html>
    <head>
    <title>
    testDTree
    </title>
    <link rel="StyleSheet" href="css/dtree.css" type="text/css" />
    </head>
    <body bgcolor="#eeeeee">
    <body leftmargin="0" topmargin="0"><table width="180">
    <tr><td height="300" valign="top" nowrap>
    <script type="text/javascript" src="js/dtree.js"></script>
    <script type='text/javascript'>
    tree = new dTree('tree');
    tree.config.folderLinks=false;
    tree.config.useCookies=false;
    <logic:iterate id="functionsForm" name="treeList" scope="request"
    type="entity.FunctionsForm">
        tree.add("<bean:write name="functionsForm" property="id"/>","<bean:write
    	name="functionsForm" property="pid"/>","<bean:write name="functionsForm"
    	property="name"/>","<bean:write name="functionsForm"
    	property="url"/>","<bean:write name="functionsForm"
    	property="title"/>","<bean:write name="functionsForm"
    	property="target"/>","<bean:write name="functionsForm" property="icon"/>");
    </logic:iterate>
          document.write(tree);
    </script>
        </td>
      </tr>
    </table>
    </body>
    </html>


        從 可以看出,我們要在mystruts目錄下,建一個(gè)名為js的目錄,并將下載的dtree文件dtree.js放在該目錄中。

        再在mystruts目錄下分別建一個(gè)名為img和名為css的目錄,將dtree中用到的圖標(biāo)和層疊樣式表單文件分別放在相應(yīng)的目錄中。

        有關(guān)dtree的使用方法,詳見其說明文檔,如:api.html。筆者在此要感謝dtree的作者為我們提供了一個(gè)結(jié)構(gòu)如此清晰的javascript程序!

        現(xiàn)在,可以編譯執(zhí)行這個(gè)例子程序了,編譯后在瀏覽器中輸入:http://127.0.0.1:8080/mystruts/functionsAction.do就可以看到運(yùn)行效果。效果圖為:



        注:dtree的下載地址為: http://www.destroydrop.com/javascripts/tree/
    主站蜘蛛池模板: 国产午夜无码片免费| 一二三四影视在线看片免费| 亚洲av片劲爆在线观看| 免费黄色福利视频| 真人无码作爱免费视频| 国产成人无码综合亚洲日韩| 无限动漫网在线观看免费| 国产精品午夜免费观看网站| 永久免费观看黄网站| 五月天网站亚洲小说| 青青青青青青久久久免费观看| 精品乱子伦一区二区三区高清免费播放| 亚洲国产成人私人影院| 日韩中文字幕在线免费观看| 中文字幕日本人妻久久久免费| 亚洲男人天堂2018av| 亚洲日韩一页精品发布| 最近中文字幕mv免费高清电影 | 亚洲综合精品成人| 亚洲中文字幕无码久久2017 | 高清在线亚洲精品国产二区| 无码精品一区二区三区免费视频 | 久久精品国产亚洲AV天海翼| 亚洲一区二区三区首页| 免费国产成人高清在线观看麻豆| 特级精品毛片免费观看| 一级毛片免费播放男男| 亚洲乱码中文论理电影| 久久精品视频亚洲| 亚洲伊人成无码综合网| 国产免费久久精品| A级毛片内射免费视频| 无码日韩精品一区二区三区免费| 国产精品亚洲一区二区三区| 亚洲一区二区三区亚瑟| 可以免费看黄的网站| 日韩免费高清播放器| 人成午夜免费大片在线观看| 亚洲另类无码专区丝袜| 亚洲一区二区三区深夜天堂| 亚洲美女视频网站|