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

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

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

    《設計模式》一書對Decorator是這樣描述的:
     動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator模式比生成子類更為靈活。
    也就是說:動態地給對象添加一些額外的功能。它的工作原理是:創建一個始于Decorator對象(負責新功能的對象)終止于原對象的一個對象的“鏈”。例如,我們要為超市的收銀臺設計一個打印票據的程序,有的需要打印票據的頭信息,有的需要打印票據的頁腳信息,有的只需要打印票據的內容。如果針對每一種情況都修改一次程序,勢必會很麻煩。這時我們可以考慮使用Decorator模式。其結構類圖如下:
     

    代碼如下:
    abstract class Component{
     abstract public void printTicket();
    }
    class SalesTicket extends Component{
     public void printTicket() {
      System.out.println("打印出salesTicket的內容");
     }
    }
    abstract class TicketDecorator extends Component{
     private Component myTrailer;
     public TicketDecorator(Component myComponent){
      myTrailer=myComponent;
     }
     public void callTrailer(){
      if(myTrailer!=null)
       myTrailer.printTicket();
     }
    }
    class Header extends TicketDecorator{
     public Header(Component myComponent){
      super(myComponent);
     }
     public void printTicket(){
      System.out.println("打印salesTicket的頭信息");
      super.callTrailer();
      
     }
    }
    class Footer extends TicketDecorator{
     public Footer(Component myComponent){
      super(myComponent);
     }
     public void printTicket(){
      super.callTrailer();
      System.out.println("打印salesTicket的頁腳信息");
     }
    }
    public class Client {

     public static void main(String[] args) {
      System.out.println("====================================");
      new Header(new Footer(new SalesTicket())).printTicket();
      System.out.println("====================================");
      new Footer(new Header(new SalesTicket())).printTicket();
      System.out.println("====================================");
     }

    }
    輸出結果如下:
    ====================================
    打印salesTicket的頭信息
    打印出salesTicket的內容
    打印salesTicket的頁腳信息
    ====================================
    打印salesTicket的頭信息
    打印出salesTicket的內容
    打印salesTicket的頁腳信息
    ====================================
    從這個例子我們可以看出,Decorator模式把問題分為兩部分:
    1) 如何實現提供新功能的對象。
    2) 如何為每種特殊情況組織對象。
    這樣能夠將Decorator對象的實現與決定如何使用Decorator的對象分離開來,從而提高了內聚性,因為每個Decorator對象只用關心自己添加的功能,無需關心自己是如何被加入到對象鏈中。還可以任意地重排Decorator的順序,無需改變其任何代碼。
    小結:Decorator模式的適用場合是,各種可選的功能在另一個肯定要執行的功能之前或之后執行。

     

    posted @ 2007-11-28 20:31 flustar 閱讀(1188) | 評論 (0)編輯 收藏

              GOF《設計模式》一書對Abstract Factory模式是這樣描述的:

        為創建一組相關或相互依賴的對象提供一個接口,而且無需指定它們的具體類。
      大致意思是說:我們在創建這些對象的時候,并不需要指定它們的具體類,這些具體類的對象是由工廠對象負責實例化的。下面是《Design Patterns Explained》一書的例子,有關計算機系統的顯示和打印程序,用來顯示和打印的分辨率取決于當前運行的系統。低端機使用低分辨率的顯示和打印驅動程序,高端機使用高分辨率的顯示和打印驅動程序。其結構圖如下:


    代碼如下:

    abstract class ResFactory{

        abstract public DisplayDriver getDisplayDrvr();

        abstract public PrintDriver getPrintDrvr();

    }

    class LowResFact extends ResFactory{

        public DisplayDriver getDisplayDrvr() {

            returnnew LRDD();

        }

        public PrintDriver getPrintDrvr() {

            returnnew LRPD();

        }

       

    }

    class HighResFact extends ResFactory{

        public DisplayDriver getDisplayDrvr() {

            returnnew HRDD();

        }

        public PrintDriver getPrintDrvr() {

            returnnew HRPD();

        }

       

    }

    abstract class DisplayDriver{

       

    }

    abstract class PrintDriver{

    }

    class HRDD extends DisplayDriver{
        
    public HRDD() {
            
    System.out.println("使用高端機的顯示驅動程序")
     } 

    }

    class LRDD extends DisplayDriver{

        public LRDD(){

            System.out.println("使用低端機的顯示驅動程序");

        } 

    }

    class HRPD extends PrintDriver{

        public HRPD() {

            System.out.println("使用高端機的打印驅動程序");

        }

       

    }

    class LRPD extends PrintDriver{

        public LRPD() {

            System.out.println("使用低端機的打印驅動程序");

        } 

    }

    public class ApControl {

        public static ResFactory getResFactory(ResFactory factory){

            return factory;

        }

        public static void main(String[] args) {

            ResFactory highResFact=ApControl.getResFactory(new HighResFact());

            highResFact.getDisplayDrvr();

            highResFact.getPrintDrvr();

            ResFactory lowResFact=ApControl.getResFactory(new LowResFact());

            lowResFact.getDisplayDrvr();

            lowResFact.getPrintDrvr();

        }

    }輸出結果:

    使用高端機的顯示驅動程序

    使用高端機的打印驅動程序

    使用低端機的顯示驅動程序

    使用低端機的打印驅動程序

        在這個例子中ApControl使用派生自兩個不同的服務類(DisplayDriver和PrintDriver)的對象。這個設計非常簡化,隱藏了實現細節,系統的可維護性也更好。ApControl不知道自己擁有的服務對象的那個特定具體實現,因為創建對象是工廠的職責。ApControl也不知道自己使用的是哪個特定工廠,因為它只知道自己有一個ResFactory對象。它可能是一個HighResFact也可能是一個LowResFact,但它不知道到底是哪一個。

        小結:在必須協調一組對象的創建時,可以應用Abstract Factory模式。它提供了一種方式,將如何執行對象實例化的規則從使用這些對象的客戶對象中提取出來。首先,找出實例化的規則,定義了一個帶接口的抽象類,其中的接口為每種需要實例化的對象提供一個方法。然后,從這個類為每個組實現具體類。最后,由客戶對象決定使用具體工廠來創建所需的對象。它主要適用于以下幾種情況:

    1)     一個系統要獨立于它的產品的創建、組合和表示時。

    2)    可以對系統進行配置,以便系統可以使用多個產品系列中的某一個。

    3)    當需要強調一系列相關產品對象的設計以便進行聯合使用時。

    4)    當希望提供一個產品類庫,而只想顯示他們的接口而不是實現時。

    posted @ 2007-11-28 20:23 flustar 閱讀(796) | 評論 (0)編輯 收藏

       《設計模式》一書對Bridge是這樣描述的:

    將抽象與其實現解耦,使它們都可以獨立地變化。

    大致意思是說:將一組實現與另一組使用他們的對象分離。這里的實現指的是抽象類及其

    派生類用來實現自己的對象(而不是抽象類的派生類,這些派生類被稱為具體類)。下面

    是《Design Patterns Explained》書中的例子。其結構圖如下:
      

    下面是它的實現:

    abstract class Shape{

        protected Drawing myDrawing;

        abstract public void draw();

        Shape(Drawing drawing){

            myDrawing=drawing;

        }

        protected void drawLine(){

            myDrawing.drawLine();

        }

        protected void drawCircle(){

            myDrawing.drawCircle();

        }

    }

    class Rectangle extends Shape{

        public Rectangle(Drawing darw){

            super(darw);

        }

        public void draw(){

            drawLine();

            drawLine();

            drawLine();

            drawLine();

        }

    }

     class Circle extends Shape{

        public Circle(Drawing draw){

            super(draw);

        }

        publicvoid draw(){

            myDrawing.drawCircle();

        }

    }

    abstract class Drawing{

        abstract public void drawLine();

        abstract public void drawCircle();

    }

    class V1Drawing extends Drawing{

        public void drawLine(){

            DP1.draw_a_line();

        }

        public void drawCircle(){

            DP1.draw_a_circle();

        }

    }

    class V2Drawing extends Drawing{

        public void drawLine(){

            DP2.drawLine();

        }

        public void drawCircle(){

            DP2.drawCircle();

        }

    }

    class DP1{

        public static void draw_a_line(){

            System.out.println("使用DP1的draw_a_line()畫線");

        }

        public static void draw_a_circle(){

            System.out.println("使用DP1的draw_a_circle()畫圓");

        }

    }

    class DP2{

        public static void drawLine(){

            System.out.println("使用DP2的drawLine()畫線");

        }

        public static void drawCircle(){

            System.out.println("使用DP2的drawCircle()畫圓");

        }

    }

     public class BridgeClient {

        public static void main(String[] args) {

            Drawing draw1=new V1Drawing();

            Drawing draw2=new V2Drawing();

            Shape shape1=new Rectangle(draw1);

            shape1.draw();

            Shape shape2=new Circle(draw2);

            shape2.draw();

        }

    }

    輸出結果如下

    使用DP1draw_a_line()畫線

    使用DP1draw_a_line()畫線

    使用DP1draw_a_line()畫線

    使用DP1draw_a_line()畫線

    使用DP2drawCircle()畫圓

    在這個例子中Shape對象實際上是一個RetangleCircle對象Client并不知道到底是那個因為它們看起來都一樣。Drawing實際上是一個V1DrawingV2Drawing,Shape對象并知道到底是哪個因為它們看起來都一樣。DP1或DP2使用它的Drawing對象知道是哪一個。Shape是事物的抽象,Drawing是實現或者操作事物方法的抽象。他們兩個都可以獨立地變化。正如例子中所說那樣,我們可以輸出一個矩形可以使用V1Drawing也可以使用V2Drawing來完成,輸出一個圓形也是一樣都有兩種方法。Bridge模式遵循了設計模式中兩條基本策略:找出變化并封裝之和優先使用對象聚集,而不是類繼承。

        小結:Bridge模式是一種抽象與其實現相分離的模式。它主要應用于:當事物是一組變化量,和對這些事物的操作方法(實現)也是一組變化量的情況,也就是說它們都是多變的。

    posted @ 2007-11-28 15:48 flustar 閱讀(1209) | 評論 (0)編輯 收藏

    GOF《設計模式》一書對Strategy模式是這樣描述的:

        定義一系列的算法,把他們一個個封裝起來,并且使它們可相互替換。Strategy模式使算法可獨立于使用它的客戶而變化。

        Strategy模式以下列幾條原則為基礎:

    1) 每個對象都是一個具有職責的個體。

    2) 這些職責不同的具體實現是通過多態的使用來完成的。

    3) 概念上相同的算法具有多個不同的實現,需要進行管理。

    下面我將通過一個實例來說明它的具體使用,這個例子是關于數據庫連接的。代碼如下:

    interface DatabaseStrategy{

        public void process();

    }

    class MysqlDBStrategy implements DatabaseStrategy{

        public void process() {

           System.out.println("處理Mysql數據庫連接");

        }

    }

    class OracleDBStrategy implements DatabaseStrategy{

        public void process() {

           System.out.println("處理Oracle數據庫連接");

        }

    }

    class DataBaseManager{

        public void process(DatabaseStrategy dbStrategy){

           dbStrategy.process();

        }

    }

    publicclass StrategyClient {

        public static void main(String[] args) {

           MysqlDBStrategy mysql=new MysqlDBStrategy();

           DataBaseManager manager=new DataBaseManager();

           manager.process(mysql);

           OracleDBStrategy oracle=new OracleDBStrategy();

           manager.process(oracle);

        }

    }

        在我們的實際編程中經常會遇到系統要連接的數據庫可能不只一種,如果采用傳統的方法,即修改連接Url的方法,這種方法確實可行,但是有一個問題要經常修改源代碼,不利于以后的維護,那么有沒有一種更好的方法呢?答案是有,使用Strategy模式,首先定義一個連接數據庫通用的接口(在上面的例子中是DatabaseStrategy),然后再定義實現該接口的具體類(MysqlDBStrategy、OracleDBStrategy),在這些具體類,實現具體的邏輯。最后再定義一個管理數據庫連接的類(DataBaseManager),它的內部有一個方法可以接受具體類實例的參數。我們可以看到這個參數是DatabaseStrategy類型的,也就是說它可以接受任何一個實現了DatabaseStrategy接口的類的具體實例(這里運用了對象替換機制,多態的一種),從而完成數據庫連接的處理。如果我們還需要處理另外一種數據庫如sqlserver,我們只需要建立一個SqlserverDBStrategy類實現DatabaseStrategy接口,把該類的實例傳給DatabaseManager的process方法即可。

        小結:Strategy模式是一種定義一系列算法的方法。概念上看,這些算法完成的都是相同的工作,只是實現不同。

    posted @ 2007-11-23 18:43 flustar 閱讀(1097) | 評論 (0)編輯 收藏

    GOF《設計模式》一書對Adapter模式是這樣描述的:
      
     將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使原本由于接口不兼容而不能一起工作的類可以一起工作。

        這段話大致是說:我們需要一種方式,為一個功能正確但接口不合的對象創建一個新接口。例如,客戶給我們如下需求:

    1) 為都有“顯示”(display)行為的點、線、正方形分別創建類。

    2) 客戶對象不必知道自己到底擁有點、線、還是正方形。它只需知道擁有這些形狀中的一個。

    也就是說,我們要用一個更高層次的概念將這些具體形狀都涵蓋進去,這個高層概念可以稱為:“可顯示的形狀”。因此,我們需要創建一個接口Shape:

    interface Shape{

        publicvoid display();

    }

    現在客戶忽然間有讓我們給這個系統增加一個畫圓的功能。這個看起來很簡單,只需定義一個Circle類來實現Shape接口,但是我們要給它編寫display方法,這可不是件簡單的事,假如此時我們正好發現一個XXCircle類,它有一個方法剛好可以完成這個功能,那么有沒有更好的方法來利用它呢,這時我們就要用到Adapter模式了。XXCircle代碼如下:

    class XXCircle{

        public void displayCircle(){

           System.out.println("通過XXCircle.displayCircle()畫圓");

        }

    }

        Adapter模式有兩種類型:

    1)    對象Adapter模式,它依賴于一個對象(適配器)包含另一個對象(被適配的對象)

    class CircleObject implements Shape{

        public XXCircle circle;

        public CircleObject(XXCircle xxcircle){

        circle=xxcircle;

        }

        public void display() {

           circle.displayCircle(); 

        }

    }

    public class Client {

        public static void main(String[] args) {

           XXCircle circle=new XXCircle();

           CircleObject co=new CircleObject(circle);

           co.display();

        }

    }

    2)     類Adapter模式,它是通過多重繼承來實現的(java中沒有多繼承,是通過接口來實現的)。

    class CircleClass extends XXCircle implements Shape{

        public void display() {

           super.displayCircle();  

        }

    }

    public class Client {

        public static void main(String[] args) {

           CircleClass cc=new CircleClass();

           cc.display();

        }

    }

        小結:Adapter模式是一個很常用的模式,它將一個(或多個)類的接口轉換成我們需要類所具備的一個接口。它的實現方式是:創建一個具備所需接口的類,然后包裝原有類的方法,這樣實際上就包含了被適配的對象。它主要適用于以下幾種情況:

    1) 你希望使用他人編寫的子程序或方法,因為你需要它所執行的功能。

    2) 你無法將這個子程序直接加入程序中。

    3) 子程序的接口或調用方式與需要使用它的相關對象不完全相同。

    posted @ 2007-11-23 18:40 flustar 閱讀(1223) | 評論 (0)編輯 收藏

            GOF《設計模式》一書對Facade模式是這樣描述的:

           為子系統中的一組接口提供一個統一接口。Facade模式定義了一個更高層的接口,使子系統更加容易使用。

           大致意思是說:使用一種比原有方式更簡單的辦法與系統交互。例如,我們把一個很文件的文件,放在了第二抽屜里,而第二個抽屜的鑰匙放在了第一個抽屜里,我們要想取出這個文件,第一步肯定要拿到第一個抽屜的鑰匙,然后打開它再拿出第二個抽屜的鑰匙,最后打開第二個抽屜取出文件。

           我就上面說的那個情形寫一下實現代碼,首先我們要實現二個子系統,呵呵,把抽屜比喻成系統,有點夸張了(DrawerOneDrawerTwo):

    class DrawerOne {

        public void open(){

           System.out.println("第一個抽屜被打開了");

           getKey();

        }

        public void getKey(){

           System.out.println("得到第二個抽屜的鑰匙");

        }

    }

    class DrawerTwo{

        public void open(){

           System.out.println("第二個抽屜被打開了");

           getFile();

        }

        public void getFile(){

           System.out.println("得到這個重要文件");

        }

    }

    public class Client{

        public static void main(String []args){

           DrawerOne darwerOne=new DrawerOne();

           DrawerTwo darwerTwo=new DrawerTwo();

           darwerOne.open();

           darwerTwo.open();

        }

    }

    由于沒有使用Façade模式,可以看到要想得到這個文件要首先打開第一個抽屜,然后再打開第二個抽屜,在我們實際所開發的系統中,有時候客戶要實現某一操作,并不需要知道實現這一操作的詳細步驟,而是簡單地點擊某一個按鈕就可以得到自己想要的結果。下面對上面的代碼使用Façade模式進行改進,建立一個FacadeDrawer類:

    class DrawerFacade{

        DrawerOne darwerOne=new DrawerOne();

        DrawerTwo darwerTwo=new DrawerTwo();

        public void open(){

           darwerOne.open();

           darwerTwo.open();

        }

    }

    修改Client類:

    public class DrawerClient{

        public static void main(String []args){

           DrawerFacade drawer=new DrawerFacade();

           drawer.open();

        }

    }

    輸出結果如下:

    第一個抽屜被打開了

    得到第二個抽屜的鑰匙

    第二個抽屜被打開了

    得到這個重要文件

    正如上面所說,客戶端client,它并不需要關心子系統,而是關心DrawerFacade所留下來的和外部交互的接口,而子系統在DrawerFacade的聚合。

    以上只是個人拙見,哪里有不正確的地方,希望大家多多批評指正。^_^

        Facade模式主要適用于以下幾種情況:

    1)    不需要使用一個復雜系統的所有功能,而且可以創建一個新的類,包含訪問系統的所有規則。如果只需要使用系統的部分功能,那么你為新類所創建的API將比原系統的API簡單的多。

    2)    希望封裝或者隱藏系統原系統。

    3)    希望使用原系統的功能,而且還希望增加一些新的功能。

    4)    編寫新類的成本小于所有人學會使用或者未來維護原系統上所需的成本。

    posted @ 2007-11-23 01:45 flustar 閱讀(2834) | 評論 (1)編輯 收藏

    一、建立xml的數據結構,文件名為:vote.xml,內容如下:

    <?xml version="1.0" encoding="UTF-8"?>

    <votes voteTotalCount="0">

        <vote voteId="1" name="c語言 " voteCount="0" percentum="0" />

        <vote voteId="2" name="c++" voteCount="0" percentum="0" />

        <vote voteId="3" name="java" voteCount="0" percentum="0" />

        <vote voteId="4" name="匯編語言" voteCount="0" percentum="0" />

     </votes>

    在你的web應用的根目錄建立xml文件夾,將其拷貝到該目錄下。

    二、建立xml對應的bean

    /**

     * @author flustar

     * @version 創建時間:Jul 11, 2007 5:17:53 PM

     * 類說明

     */

    ……………………………………………………………………….

    ……………………………………………………………………….

    public class VoteBean {

        private String voteId;

       private String name;

        private String voteCount;

        private String voteTotalCount;

        private String percentum;

        public VoteBean() {

          

        }

        public String getPercentum() {

           return percentum;

        }

        public void setPercentum(String percentum) {

           this.percentum = percentum;

        }

        public String getVoteId() {

           return voteId;

        }

     

        public void setVoteId(String voteId) {

           this.voteId = voteId;

        }

        public String getName() {

           return name;

        }

        public void setName(String name) {

           this.name = name;

        }

        public String getVoteCount() {

           return voteCount;

        }

     

        public void setVoteCount(String voteCount) {

           this.voteCount = voteCount;

        }

    }

    三、建立處理具體邏輯的service

    package com.flustar.service;

    import java.io.FileInputStream;

    import java.io.FileOutputStream;

    import java.text.NumberFormat;

    import java.util.ArrayList;

    import java.util.Iterator;

    import java.util.List;

    import org.jdom.Attribute;

    import org.jdom.Document;

    import org.jdom.Element;

    import org.jdom.input.SAXBuilder;

    import org.jdom.output.Format;

    import org.jdom.output.XMLOutputter;

    import org.jdom.xpath.XPath;

    import com.flustar.web.beans.VoteBean;

    import com.flustar.web.config.ContextConfig;

    public class VoteService {

           private Element root, vote;

           private Document doc;

          private Attribute voteTotalCount;

           private VoteBean voteBean;

           private List<VoteBean> voteBeanList;

           private String path = ContextConfig.getContextPath()

                         + "/xml/vote.xml";

           public void buildDoc() throws Exception {

                  FileInputStream fi = null;

                  fi = new FileInputStream(path);

                  SAXBuilder sb = new SAXBuilder();

                  doc = sb.build(fi);

           }

           public void formatDoc() throws Exception {

                  Format format = Format.getCompactFormat();

                  format.setEncoding("UTF-8");// 設置xml文件的字符為UTF-8

                  format.setIndent("    ");// 設置xml文件縮進為4個空格

                  XMLOutputter xmlOut = new XMLOutputter(format);

                  xmlOut.output(doc, new FileOutputStream(path));

           }

     

           public String floatToPercentum(Double doubleNum) {

                  NumberFormat numberFormat = NumberFormat.getPercentInstance();

                  numberFormat.setMinimumFractionDigits(2);

                  // numberFormat.setMaximumIntegerDigits(2);

                  String str = numberFormat.format(doubleNum);

                  //System.out.println(str);

                  return str;

           }

     

           public void updateVoteCount(String voteId) throws Exception {

                  buildDoc();

                  root = doc.getRootElement();

                  vote = (Element) XPath.selectSingleNode(root, "http://vote[@voteId='"

                                + voteId + "']");

                  int voteCount = Integer.parseInt(vote.getAttributeValue("voteCount")) + 1;

                  //System.out.println(voteCount);

                  vote.setAttribute("voteCount", String.valueOf(voteCount));

                  int totalCount = Integer.parseInt(root

                                .getAttributeValue("voteTotalCount")) + 1;

                  voteTotalCount = new Attribute("voteTotalCount", String

                                .valueOf(totalCount));

                  root.setAttribute(voteTotalCount);

                  System.out.println(totalCount);

                  formatDoc();

                  updateAllVoteCount();//更新所有的百分比

     

           }

        public void updateAllVoteCount()throws Exception{

               buildDoc();

               root=doc.getRootElement();

               int totalCount = Integer.parseInt(root

                                .getAttributeValue("voteTotalCount"));

               List voteList=XPath.selectNodes(root,"/votes/vote");

               for(int i=0;i<voteList.size();i++){

                      vote=(Element)voteList.get(i);

                      int voteCount = Integer.parseInt(vote.getAttributeValue("voteCount"));

                      System.out.println(voteCount);

                      vote.setAttribute("voteCount", String.valueOf(voteCount));

                      vote.setAttribute("percentum", floatToPercentum(1.0 * voteCount

                                    / totalCount));

               }

               formatDoc();

        }

           public List getAllVote() throws Exception {

                  buildDoc();

                  voteBeanList = new ArrayList();

                  root = doc.getRootElement();

                  String totalCount = root.getAttributeValue("voteTotalCount");

                  List voteList = root.getChildren();

                  Iterator i = voteList.iterator();

     

                  while (i.hasNext()) {

                         voteBean = new VoteBean();

                         voteBean.setVoteTotalCount(totalCount);

                         vote = (Element) i.next();

                         String name = vote.getAttributeValue("name");

                         String voteCount = vote.getAttributeValue("voteCount");

                         String percentum = vote.getAttributeValue("percentum");

     

                         voteBean.setName(name);

                         voteBean.setVoteCount(voteCount);

                         voteBean.setPercentum(percentum);

                         voteBeanList.add(voteBean);

                  }

                  return voteBeanList;

           }

     

    }

     

        public String getVoteTotalCount() {

           return voteTotalCount;

        }

     

        public void setVoteTotalCount(String voteTotalCount) {

           this.voteTotalCount = voteTotalCount;

        }

    }

     

    四、獲取上下文路徑的listener

    package com.flustar.web.listener;

    import javax.servlet.ServletContextEvent;

    import javax.servlet.ServletContextListener;

    import com.flustar.web.config.ContextConfig;

    public class ConfigLoadContextListener implements  ServletContextListener{

        public void contextDestroyed(ServletContextEvent arg0) {

           // TODO Auto-generated method stub

               }

        public void contextInitialized(ServletContextEvent contextEvent) {

           // TODO Auto-generated method stub

                  String contextPath = contextEvent.getServletContext().getRealPath("/");

           ContextConfig.setContextPath(contextPath);

               }

    }

    ………………………………………………………..

    ……………………………………………………………

     

    public class ContextConfig {

        private static String contextPath;

     

        public static String getContextPath() {

           return contextPath;

        }

     

        public static void setContextPath(String contextPath) {

           ContextConfig.contextPath = contextPath;

        }

    ……………………………………………………………………

    ………………………………………………………………..

    }

    五、在applicationContext-service.xml中注冊VoteService

    <bean name="voteService" class="com.flustar.service.imp.VoteService"/>

    六、注冊xml,在你的web應用的WEB-INFO目錄下建立applicationContext-dwr.xml文件,內容為:

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">

    <dwr>

        <allow>

          <create  creator="spring" javascript="VoteService" >

             <param name="beanName" value="voteService"></param>

             <include method="updateVoteCount"/>

             <include method="getAllVote"/>

          </create>

          <convert converter="bean"  match="com.flustar.web.beans.VoteBean" />

               </allow>

    </dwr>

     

    七、修改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"

        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"

        version="2.4">

        …………………………………………………………………………………………………………………………

    ………………………………………………………………………………………………………………………………..

        <context-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>

    …………………………………..

           /WEB-INF/classes/applicationContext-service.xml

    </param-value>

        </context-param>

     …………………………………………………………………………………………………………………………………………….     <listener-class>com.flustar.web.listener.ConfigLoadContextListener</listener-class>

        …………………………………………………………………………………………………………………………………………….   

      <servlet>

        <servlet-name>dwr-invoker</servlet-name>

        <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>

        <init-param>

          <param-name>debug</param-name>

          <param-value>true</param-value>

        </init-param>

      </servlet>

     

      <servlet-mapping>

        <servlet-name>dwr-invoker</servlet-name>

        <url-pattern>/dwr/*</url-pattern>

      </servlet-mapping> 

    …………………………………………………………………………………………………………………………………………….   

    </web-app>

    八、jsp頁面

    1)

    <%@ page contentType="text/html; charset=gbk" language="java" import="java.sql.*" errorPage="" %>

    <html>

    <head>

    <title>投票系統</title>

           <script type='text/javascript' src='dwr/engine.js'> </script>

            <script type='text/javascript' src='dwr/util.js'> </script>

            <script type='text/javascript' src='dwr/interface/VoteService.js'> </script>

           <script type='text/javascript'>

    function vote(){

           

         var   obj=document.getElementsByName('radio'); 

        

             if   (obj!=null){ 

             var j=0;

               for   (var   i=0;i<obj.length;i++){ 

                 if   (obj[i].checked)  

                  {  

                   

                       VoteService.updateVoteCount(obj[i].value);

                       alert("投票成功!");

                      obj[i].checked=false;

                      break;

                   }

                  }

                   j=j+1;

                 

              }

             if(j==obj.length){

                    alert("請選中其中的一項,再投票!");

                   }

              

          }

       

        }

      function showwin(){

        window.open('voteresult.htm','voteresult','height=400, width=400, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no');

       }

     }

    </script>

    </head>

    <body>

    <div >

        <h1 >

           你使用最多的一門語言是?

        </h1>

    </div>

    <div>

    <div>

            <span>     <h1><input type="radio" name="radio" id="radio" value="1" />

           C語言</h1>

            </span>

           <span> <h1 ><input type="radio" name="radio" id="radio" value="2" />c++ </h1> </span>

           <span ><h1 ><input type="radio" name="radio" id="radio" value="3" />java </h1> </span>

           <span><h1 ><input type="radio" name="radio" id="radio" value="4"/>匯編語言</h1> </span>

    </div>

    </div>

    <div id="toupiao"><input class="btn" type="button" value="投票" onClick="vote()" /><input class="btn" type="button" value="查看" onClick="showwin()"/></div>

    </body>

    </html>

    2)

    <html>

    <head>

    <meta http-equiv="content-type" content="text/html; charset=gb2312">

    <title>投票結果</title>

           <script type='text/javascript' src='dwr/engine.js'> </script>

            <script type='text/javascript' src='dwr/util.js'> </script>

            <script type='text/javascript' src='dwr/interface/VoteService.js'> </script>

            <script type='text/javascript' >

    function showresult(){

                 VoteService.getAllVote(function(data){

                 document.getElementById("totalCount").innerHTML=data[0].voteTotalCount;

                 for(var i=0;i<data.length;i++){

                      var voteBean=data[i];

                      document.getElementById("xuanshou"+i).innerHTML=voteBean.name;

                      document.getElementById("baifenbi"+i).innerHTML=voteBean.percentum;

                      document.getElementById("piaoshu"+i).innerHTML=voteBean.voteCount;

                      document.getElementById("img"+i).width=voteBean.voteCount/data[0].voteTotalCount*310;

                                       

          }

        });

              

    }

    </script>

    </head>

    <body onLoad="showresult()">

    <div id="voteRs">

    <table border="0" cellpadding="0" cellspacing="0">

      <CAPTION valign="top" class="subject">

    投票結果

        </CAPTION>

      <tbody>

      <tr >

        <th>語言</th>

        <th>百分比</th>

        <th>票數</th>

      </tr>

      <tr>

        <td><span id="xuanshou0"></span></td>

        <td><span id="baifenbi0"></span><img id="img0" src='images/voteprogress.gif' width=0 height=10></td>

        <td><span id="piaoshu0"></span></td>

      </tr>

      <tr>

        <td><span id="xuanshou1"></span></td>

        <td><span id="baifenbi1"></span><img id="img1" src='images/voteprogress.gif' width=0 height=10></td>

        <td><span id="piaoshu1"></span></td>

      </tr>

      <tr>

        <td><span id="xuanshou2"></span></td>

        <td><span id="baifenbi2"></span><img id="img2" src='images/voteprogress.gif' width=0 height=10></td>

        <td><span id="piaoshu2"></span></td>

      </tr>

       <tr>

        <td><span id="xuanshou3"></span></td>

        <td><span id="baifenbi3"></span><img id="img3" src='images/voteprogress.gif' width=0 height=10></td>

        <td><span id="piaoshu3"></span></td>

      </tr>

     

      </tbody>

    </table>

    共<span id="totalCount"></span>條投票<br/>

    [<span onClick="javascript:window.close();">關閉窗口</span>]

    </div>

    </body>

    </html>

     

    posted @ 2007-11-19 18:04 flustar 閱讀(1363) | 評論 (0)編輯 收藏

    最近發現使用prototype來做表單的前臺驗證感覺非常不錯,prototype.js 是由 Sam Stephenson 寫的一個 javascript 類庫。這個構思奇妙,而且兼容標準的類庫,能幫助你輕松建立有高度互動的 Web 2.0 特性的富客戶端頁面。下面是一個使用它做前臺表單驗證的例子。

    var flag=[true,true,true,true,true,true,true,true,true,true];
           var userNameInfo=["用戶名不能為空","用戶名必須為6~20位","用戶已存在","恭喜用戶名可以使用"];
           var passwordInfo=["密碼不能為空","密碼長度不能小于6位","請再次輸入密碼","兩次密碼輸入不一致,請重新輸入"];
           function changeImage()
        {
        var timenow=new Date().getTime();
              $('checkcode').src = "image/loading.gif";
              $('checkcode').src = "random.jsp?d="+timenow;
           }
           function checkUserName()
        {
        if ($F("userName").match(/^\s*$/g)) {
               $("userNameErr").innerHTML =userNameInfo[0];
         flag[0]=false;
          }else{
      
        var re=/^(\w){6,20}$/;
        var tt = re.test($F("userName"));
        if(tt==false){
       $("userNameErr").innerHTML = userNameInfo[1];
       flag[0]=false;
           }else{
         $("userNameErr").innerHTML = "<img src='image/loading.gif'>";
           isExsitUsername(); 
       }
        }
       }
        function checkPassword()
        {
         
        if ($F("password").match(/^\s*$/g)) {
               $("pwdErr").innerHTML =passwordInfo[0];
               flag[1]=false;
      }else if($F("password").length<6){
          $("pwdErr").innerHTML=passwordInfo[1];
          flag[1]=false;
      }else{
          $("pwdErr").innerHTML="";
          flag[1]=true;
      }
      
        }
        function checkRePassword(){
          if ($F("password2").match(/^\s*$/g)) {
              $("repwdErr").innerHTML =passwordInfo[2];
              flag[2]=false;
      }else if($F("password2")!=$F("password")){
       $("repwdErr").innerHTML=passwordInfo[3]; 
       flag[2]=false; 
       }else{
          $("repwdErr").innerHTML="";
          flag[2]=true;
       }
        }
        function checkName(){
           if($F("name").match(/^\s*$/g)){
          $("nameErr").innerHTML="昵稱不能為空";
          flag[3]=false;
        }else{
         $("nameErr").innerHTML="";
         flag[3]=true;
        }
        }
        function checkQuestion(){
           if($F("question").match(/^\s*$/g)){
              $("questionErr").innerHTML="請選擇一個安全問題";
              flag[4]=false;
           }else{
              $("questionErr").innerHTML="";
              flag[4]=true;
           }
        }
        function checkAnswer(){
          if($F("answer").match(/^\s*$/g)){
             $("answerErr").innerHTML="安全回答不能為空";
             flag[5]=false;
          }else if($F("answer").length<4){
             $("answerErr").innerHTML="安全回答問題不能少于4個字符";
             flag[5]=false;
          }else{
              $("answerErr").innerHTML="";
             flag[5]=true;
          }
        }
        function checkEmail()
        {
         var reEmail =/(\S)+[@]{1}(\S)+[.]{1}(\w)+/;
          if($F("email").match(/^\s*$/g)){
             $("emailErr").innerHTML="Email不能為空";
             flag[6]=false;
          }else{
               var temp=reEmail.test($("email").value);
               if(temp==false){
                 $("emailErr").innerHTML= "Email必須符合要求!";
                    flag[6]=false;
                  }else{
                    $("emailErr").innerHTML="<img src='image/loading.gif'>";
                                 isExsitEmail();
                 
                  }
             }

        }
        function checkMobile(){
        var patrn=/^(?:13\d|15[89])-?\d{5}(\d{3}|\*{3})$/;
        if($F("mobile").match(/^\s*$/g)){
             $("mobileErr").innerHTML="";
          flag[7]=true;
        }else{
          if (!patrn.test($F("mobile"))) {
             $("mobileErr").innerHTML="請輸入正確的手機號碼";
             flag[7]=false;
          }else{
            $("mobileErr").innerHTML="";
            flag[7]=true;
          }
          
        }  
          
       }
       function checkPID(){
         var patrn=/(^\d{15}$)|(^\d{17}([0-9]|X|x)$)/;
         if($F("PID").match(/^\s*$/g)){
           $("PIDErr").innerHTML="";
           flag[8]=true;
         }else{
          if (!patrn.test($F("PID")))  
             {
             $("PIDErr").innerHTML="身份證號碼有誤!";
             flag[8]=false;
          }else{
           $("PIDErr").innerHTML="";
           flag[8]=true;
        }
       }
           
        }
       
      function isExsitUsername(){
         var username=$F("userName");
         var url='user_checkUsername.do';
         var pars="username="+username;
         var usernameAjax=new Ajax.Request(
           url,
           {method:'get',parameters:pars,onComplete:showUResult}
           );
      }
      function showUResult(result){
      
           if(result.responseText.indexOf("true")!=-1){
              
              $("userNameErr").innerHTML=userNameInfo[2];
              flag[0]=false;
           }else{
              $("userNameErr").innerHTML="<font color='green'>"+userNameInfo[3]+"</font>";
              flag[0]=true;
           }
      }
      function isExsitEmail(){
         var email=$F("email");
         var url='user_checkEmail.do';
         pars="email="+email;
         var emailAjax=new Ajax.Request(
            url,
            {method:'get',parameters:pars,onComplete:showEResult}
            );
      }
      function showEResult(result){
       if(result.responseText.indexOf("true")!=-1){
           $("emailErr").innerHTML="這個Email已經有人使用,請換一個";
           flag[6]=false;
       }else{
           $("emailErr").innerHTML="<font color='green'>已通過驗證</font>";
           flag[6]=true;
       }
      }
      function checkCode(){
          if($("code").value.match(/^\s*$/g)){
             $("codeErr").innerHTML="驗證碼不能為空";
             flag[9]=false;
        }else{
          isCorrectCode();
        }
        }
      function isCorrectCode(){
         var code=$F("code");
         var url='checkcode.jsp';
         pars="code="+code+"&ram="+Math.random();
         var codeAjax=new Ajax.Request(
         url,
         {method:'get',parameters:pars,asynchronous:false,onComplete:showCResult}
         );
        
      }
      function showCResult(result){
         if(result.responseText.indexOf("validate_successful")!=-1){
           $("codeErr").innerHTML="";
           flag[9]=true;
         }else{
           $("codeErr").innerHTML="錯誤的驗證碼";
           flag[9]=false;
         }
      }
     function checkform(){
          checkUserName();
          checkPassword();
          checkRePassword();
          checkName();
          checkQuestion();
          checkAnswer();
          checkEmail();
          checkMobile();
          checkPID();
          checkCode();
          for(var i=0;i<flag.length;i+=1){
            if(flag[i]==false)
              return false;
         }
         return true;
         
       }
    其中

    $(): 函數是在 DOM 中使用過于頻繁的 document.getElementById() 方法的一個便利的簡寫,就像這個 DOM 方法一樣,這個方法返回參數傳入的 id 的那個元素。
    $F() :函數是另一個大收歡迎的“快捷鍵”,它能用于返回任何表單輸入控件的值,比如文本框或者下拉列表。這個方法也能用元素 id 或元素本身做為參數。
    Ajax.Request 類:如果你不使用任何的幫助程序包,你很可能編寫了整個大量的代碼來創建 XMLHttpRequest 對象并且異步的跟蹤它的進程,然后解析響應并處理它。當你不需要支持多于一種類型的瀏覽器時你會感到非常的幸運,反之你就要考慮使用prototype的Ajax.Request類。你也許注意到了在使用它做無刷新驗證用戶名,Email以及驗證碼時,使用'get'方法把參數傳遞給url,后面都帶有一個參數,這個參數值是當前系統時間或是一個隨機參數的一個數,這樣做是為了避免瀏覽器的從它的緩存中讀取響應信息,影響結果的正確性。


     

    posted @ 2007-11-15 15:43 flustar 閱讀(1130) | 評論 (0)編輯 收藏

        時間過得真快,已經半年沒有更新自己的博客了。    好了,言歸正傳。大家都知道網上廣為流傳的一個分頁類是:PaginationSupport.java其源代碼如下:
        

    public class PaginationSupport{

     public final static int PAGESIZE = 30;

     private int pageSize = PAGESIZE;

     private List items;

     private int totalCount;

     private int[] indexes = new int[0];

     private int startIndex = 0;

     public PaginationSupport(List items, int totalCount) {
      setPageSize(PAGESIZE);
      setTotalCount(totalCount);
      setItems(items);
      setStartIndex(0);
     }

     public PaginationSupport(List items, int totalCount, int startIndex) {
      setPageSize(PAGESIZE);
      setTotalCount(totalCount);
      setItems(items);
      setStartIndex(startIndex);
     }

     public PaginationSupport(List items, int totalCount, int pageSize,
       int startIndex) {
      setPageSize(pageSize);
      setTotalCount(totalCount);
      setItems(items);
      setStartIndex(startIndex);
     }

     public List getItems() {
      return items;
     }

     public void setItems(List items) {
      this.items = items;
     }

     public int getPageSize() {
      return pageSize;
     }

     public void setPageSize(int pageSize) {
      this.pageSize = pageSize;
     }

     public int getTotalCount() {
      return totalCount;
     }

     public void setTotalCount(int totalCount) {
      if (totalCount > 0) {
       this.totalCount = totalCount;
       int count = totalCount / pageSize;
       if (totalCount % pageSize > 0)
        count++;
       indexes = new int[count];
       for (int i = 0; i < count; i++) {
        indexes[i] = pageSize * i;
       }
      } else {
       this.totalCount = 0;
      }
     }

     public int[] getIndexes() {
      return indexes;
     }

     public void setIndexes(int[] indexes) {
      this.indexes = indexes;
     }

     public int getStartIndex() {
      return startIndex;
     }

     public void setStartIndex(int startIndex) {
      if (totalCount <= 0)
       this.startIndex = 0;
      else if (startIndex >= totalCount)
       this.startIndex = indexes[indexes.length - 1];
      else if (startIndex < 0)
       this.startIndex = 0;
      else {
       this.startIndex = indexes[startIndex / pageSize];
      }
     }

     public int getNextIndex() {
      int nextIndex = getStartIndex() + pageSize;
      if (nextIndex >= totalCount)
       return getStartIndex();
      else
       return nextIndex;
     }

     public int getPreviousIndex() {
      int previousIndex = getStartIndex() - pageSize;
      if (previousIndex < 0)
       return 0;
      else
       return previousIndex;
     }

     public int getPageCount() {
      int count = totalCount / pageSize;
      if (totalCount % pageSize > 0)
       count++;
      return count;
     }

     public int getCurentPageNum() {
      return getStartIndex() / pageSize + 1;
     }

    }
    在這個分頁類中設定了每頁要顯示的記錄數以及開始索引,如果用普通的jsp來取這個分頁類的數據還可以,但是使用spring+hibernate這種架構就顯得比較麻煩(原因是spring MVC返回的是一個 PaginationSupport的對象,使用jstl作為前端顯示的話,會在jsp頁面中摻雜大量的計算,像下一頁索引,共多少條記錄,當前第幾頁,共多少頁等等會使jsp很難維護)下面是對這個類的改進:

    public class  PaginationSupport {
     public final static int PAGESIZE = 30;

     private int pageSize = PAGESIZE;
     
     private int totalCount;

     private int currentPage;

     private int startIndex;
     
     private int[] indexes = new int[0];
     
     private int nextIndex;

     private int previousIndex;

     private int pageCount;

     private List items;
     
     private int lastIndex;
     
     public  PaginationSupport(int pageSize,
       int startIndex) {
      setPageSize(pageSize);
      setStartIndex(startIndex);
      
     }

     public  PaginationSupport(List items, int totalCount) {
      setPageSize(PAGESIZE);
      setTotalCount(totalCount);
      setItems(items);
      setStartIndex(0);
     
     }

     public  PaginationSupport(List items, int totalCount, int startIndex) {
      setPageSize(PAGESIZE);
      setTotalCount(totalCount);
      setItems(items);
      setStartIndex(startIndex);
      
     }

     public  PaginationSupport(List items, int totalCount, int pageSize,
       int startIndex) {
      setPageSize(pageSize);
      setTotalCount(totalCount);
      setItems(items);
      setStartIndex(startIndex);
      
     }

     
     public void setTotalCount(int totalCount) {
      if (totalCount > 0) {
       this.totalCount = totalCount;
       int count = totalCount / pageSize;
       if (totalCount % pageSize > 0)
        count++;
       indexes = new int[count];
       for (int i = 0; i < count; i++) {
        indexes[i] = pageSize * i;
       }
        } else {
       this.totalCount = 0;
      }
     }
     public int getTotalCount() {
      return totalCount;
     }
     public void setIndexes(int[] indexes) {
      this.indexes = indexes;
     }
     public int[] getIndexes() {
      return indexes;
     }

     
     public void setStartIndex(int startIndex) {
      if (totalCount <= 0)
       this.startIndex = 0;
      else if (startIndex >= totalCount)
       this.startIndex = indexes[indexes.length - 1];
      else if (startIndex < 0)
       this.startIndex = 0;
      else {
       this.startIndex = indexes[startIndex / pageSize];
      }
       }
     public int getStartIndex() {
      return startIndex;
     }

     
     public void setNextIndex(int nextIndex) {
      this.nextIndex = nextIndex;
     }
     public int getNextIndex() {
      int nextIndex = getStartIndex() + pageSize;
      if (nextIndex >= totalCount)
       return getStartIndex();
      else
       return nextIndex;
     }
     public void setPreviousIndex(int previousIndex) {
      this.previousIndex = previousIndex;
     }
     
     public int getPreviousIndex() {
      int previousIndex = getStartIndex() - pageSize;
      if (previousIndex < 0)
       return 0;
      else
       return previousIndex;
     }
     public void setPageCount(int pageCount) {
      this.pageCount = pageCount;
     }
     public int getPageCount() {
      int count = totalCount / pageSize;
      if (totalCount % pageSize > 0)
       count++;
      return count;
     }
     

     public int getCurrentPage() {
      return getStartIndex() / pageSize + 1;
     }

     public void setCurrentPage(int currentPage) {
      this.currentPage = currentPage;
     }

     public void setLastIndex(int lastIndex) {
      this.lastIndex =lastIndex ;
     }
     public int getLastIndex() {
      return indexes[indexes.length-1];
     }

     
     public int getPageSize() {
      return pageSize;
     }

     public void setPageSize(int pageSize) {
      this.pageSize = pageSize;
     }

     

     public List getItems() {
      return items;
     }

     public void setItems(List items) {
      this.items = items;
     }


    }
    以上是分頁的封裝類,下面是支持分頁查詢的方法:
    1)
    public PaginationSupport findPageByCriteria(
       final DetachedCriteria detachedCriteria, final int pageSize,
       final int startIndex) {
      return (PaginationSupport) getHibernateTemplate().execute(
        new HibernateCallback() {
         public Object doInHibernate(Session session)
           throws HibernateException {
          Criteria criteria = detachedCriteria
            .getExecutableCriteria(session);
          int totalCount = ((Integer) criteria.setProjection(
            Projections.rowCount()).uniqueResult())
            .intValue();
          criteria.setProjection(null);
          List items = criteria.setFirstResult(startIndex)
            .setMaxResults(pageSize).list();
          PaginationSupport ps = new PaginationSupport(items,
            totalCount, pageSize, startIndex);
          return ps;
         }
        }, true);
     }
    2)
    public  PaginationSupport findPageByQuery( final  String hsql,  final int pageSize,final int startIndex){
         return (PaginationSupport)getHibernateTemplate().execute(
         new  HibernateCallback() {
           public  Object doInHibernate(Session session)  throws  HibernateException, SQLException {
                 Query query  =  session.createQuery(hsql);
                 int totalCount=query.list().size();
                 query.setFirstResult(startIndex);
                 query.setMaxResults(pageSize);
                 List items  = query.list();
              PaginationSupport ps = new PaginationSupport(items,
           totalCount, pageSize, startIndex);
              return ps;
                
                 }
           },true);
      }
    你也許會問分頁查詢為什么會提供兩個方法,這兩個方法有區別嗎?其實這兩個方法并無本質區別,DetachedCriteria 也是構造查詢語句的與Query功能一致,但是它提供了更加面向對象的方法來寫hsql語句。一般人們都傾向第一種方法,但是這種方法并不通用,它有一種查詢并不支持,那就是當你要查詢的對象并不是一個單一對象的話(例如 你在數據庫中有兩個表,一個是user,另一個是userinfo,這兩個表所對應的對象在hiberante中被指定為共享主鍵的話,在執行查詢的時候就會報類型轉換異常,原因是查詢出來的對象并不是user而是一個包含user 和userinfo的Object,你若強制把它轉換成user類型,肯定會出錯),這時你不得不采用第二個方法。當然這只是我個人見解,也許還有地方說的不是很準確,希望大家多多批評指正。
    最后是這個分頁類的前臺顯示源代碼:
    <%@ page language="java" contentType="text/html; charset=gbk"
        pageEncoding="GBK"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
      <link type="text/css" rel="stylesheet" href="../css/panel.css">
        <title>顯示所有用戶</title>
      </head>
     
      <body>
        <div style="margin:20px auto 30px; width:70%;"><a href="index.jsp" class="btn2">返回首頁</a></div>
        <div style="margin:10px auto 0; width:70%;">
        <table width="100%" border="0" cellpadding="0" cellspacing="0">
        <caption>
          顯示所有用戶
        </caption>
        <tr>
          <td>用戶ID</td>
          <td>用戶名</td>
       <td>用戶昵稱</td>
          <td>電子郵件</td>
          <td>注冊時間</td>
          <td>詳細信息</td>
          <td>用戶充值記錄</td>
          <td>用戶定制服務信息</td>
        </tr>
    <c:forEach var="user" items="${userPage.items}">
     <tr>
       <td>${user.intId}</td>
          <td>${user.username}</td>
          <td>${user.name}</td>
          <td>${user.email}</td>
          <td><fmt:formatDate value='${user.creationTime}' pattern='yyyy-MM-dd HH:mm' /></td>
       <td><a href="user_getdetailUser.ado?userId=${user.intId}" class="btn">詳細信息</a></td>
       <td><a href="orderService_getUserAccountAdds.ado?userId=${user.intId}" class="btn">用戶充值記錄</a></td>
       <td><a href="orderService_getUserChargeItems.ado?userId=${user.intId}" class="btn">用戶定制服務信息</a></td>
     </tr>
    </c:forEach>
      </table>
       <c:if test="${!empty userPage}">
         共${userPage.totalCount}記錄
         <c:choose>
          <c:when test="${userPage.startIndex ne '0'}">
           <a href="user_getPage.ado?startIndex=0">首頁</a>
          </c:when>
          <c:otherwise>
           首頁
          </c:otherwise>
         </c:choose>
         <c:choose>
          <c:when test="${userPage.previousIndex lt userPage.startIndex}">
           <a href="user_getPage.ado?startIndex=${userPage.previousIndex }">上一頁</a>
          </c:when>
          <c:otherwise>
           上一頁
          </c:otherwise>
         </c:choose>
         <c:choose>
          <c:when test="${userPage.nextIndex>userPage.startIndex}">
           <a href="user_getPage.ado?startIndex=${userPage.nextIndex}">下一頁</a>
          </c:when>
          <c:otherwise>
           下一頁
          </c:otherwise>
         </c:choose>
         <c:choose>
          <c:when test="${userPage.lastIndex eq userPage.startIndex}">
           最后一頁
          </c:when>
          <c:otherwise>
           <a href="user_getPage.ado?startIndex=${userPage.lastIndex}">最后一頁</a>
          </c:otherwise>
         </c:choose>
         每頁顯示${userPage.pageSize}條記錄
         當前第${userPage.currentPage }/${userPage.pageCount}頁
      </c:if>
        </div>
      </body>
    </html>


    posted @ 2007-11-13 10:50 flustar 閱讀(5364) | 評論 (6)編輯 收藏

    dtree動態樹+Javascript右鍵菜單(一)
    1、從網上下載dtree控件。(好多地方都有的哦:P)
    2、在Jbuilder中新建Web應用,命名為TreeLearing
    3、解壓縮dtree.rar包。
        把dtree目錄拷貝至TreeLearing應用中。
        dtree目錄下包括這些文件:example01.html 、 dtree.js 、 api.html 、 dtree.css 和img目錄
        注意:除了api.html之外,其它的文件都是必須拷貝的。只有這個api.html是對dtree控件的函數介紹。
    4、復制example01.html,并把粘貼后的文件重命名為Tree.jsp
    :)  (保留原來的文件,以備參考是個好習慣哦~~)
    注意dtree目錄下的文件結構不要改變,否則樹就不會正常顯示
     
    5、在Web應用中指定首頁為Tree.jsp頁面。
    6、Tree.jsp中的代碼如下:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" " <html>
    <head>
     <title>Destroydrop &raquo; Javascripts &raquo; Tree</title>
     <link rel="StyleSheet" href="dtree.css" type="text/css" />
     <script type="text/javascript" src="dtree.js"></script>
    </head>
    <body>
    <h1><a href="/">Destroydrop</a> &raquo; <a href="/javascripts/">Javascripts</a> &raquo; <a href="/javascripts/tree/">Tree</a></h1>
    <h2>Example</h2>
    <div class="dtree">
     <p><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>
     <script type="text/javascript">
      <!--
      d = new dTree('d');
      d.add(0,-1,'My example tree');
      d.add(1,0,'Node 1','example01.html');
      d.add(2,0,'Node 2','example01.html');
      d.add(3,1,'Node 1.1','example01.html');
      d.add(4,0,'Node 3','example01.html');
      d.add(5,3,'Node 1.1.1','example01.html');
      d.add(6,5,'Node 1.1.1.1','example01.html');
      d.add(7,0,'Node 4','example01.html');
      d.add(8,1,'Node 1.2','example01.html');
      d.add(9,0,'My Pictures','example01.html','Pictures I\'ve taken over the years','','','img/imgfolder.gif');
      d.add(10,9,'The trip to Iceland','example01.html','Pictures of Gullfoss and Geysir');
      d.add(11,9,'Mom\'s birthday','example01.html');
      d.add(12,0,'Recycle Bin','example01.html','','','img/trash.gif');
      document.write(d);
      //-->
     </script>
    </div>
    </body>
    </html>
     
    7、刪除紫紅色部分的代碼,因為不需要哦。
    8、注意看綠色和藍色部分的代碼,這才是真正為樹添加節點的部分。
        d.add(0,-1,'My example tree');
        這一句為樹添加了一個根節點,顯示名稱為'My example tree'
        d.add(1,0,'Node 1','example01.html');
        這一句在樹的根節點下面添加了一個子節點。(d.add()方法的參數具體含義可參見api.html文件)
        常用的:
        第一個參數,表示當前節點的ID
        第二個參數,表示當前節點的父節點的ID
        第三個參數,節點要顯示的文字
        第四個參數,點擊該節點的超鏈接(注意也可以是某個servlet或是struts應用中的某個.do請求)
        第五個參數,鼠標移至該節點時顯示的文字
        第六個參數,指定點擊該節點時在哪個楨中打開超鏈接
        ……
    9、運行應用程序。可以看到一棵漂亮的樹。
    原貼地址
    http://blog.sina.com.cn/u/4ae9618f010006y3

    posted @ 2007-04-29 14:20 flustar 閱讀(2089) | 評論 (0)編輯 收藏

    僅列出標題
    共6頁: 上一頁 1 2 3 4 5 6 下一頁 

    posts - 146, comments - 143, trackbacks - 0, articles - 0

    Copyright © flustar

    主站蜘蛛池模板: 亚洲亚洲人成综合网络| 自拍偷区亚洲国内自拍| 91嫩草免费国产永久入口| 亚洲av无码专区在线观看亚| 亚洲色WWW成人永久网址| 中文字幕成人免费视频| 国产成人亚洲精品播放器下载| 亚洲人成网7777777国产| 无码一区二区三区AV免费| 一级黄色片免费观看| 亚洲三级中文字幕| 久久久久亚洲AV成人网| xxxx日本免费| 久久免费99精品国产自在现线| 亚洲国产日韩精品| 亚洲va中文字幕无码久久不卡| 成人免费无码大片a毛片| 精品一区二区三区免费| 亚洲日韩AV一区二区三区中文| 亚洲精品成人无限看| 免费看AV毛片一区二区三区| 久久免费观看国产精品| 精品一区二区三区无码免费直播| 亚洲黄网站wwwwww| 不卡精品国产_亚洲人成在线| 欧美在线看片A免费观看| 久久精品国产大片免费观看| 色网站在线免费观看| 精品国产成人亚洲午夜福利| 亚洲爱情岛论坛永久| 亚洲国产精品日韩| 日韩免费高清视频网站| 亚洲成人在线免费观看| 三年片在线观看免费| 免费人妻精品一区二区三区| 国产成人亚洲精品| 亚洲精品熟女国产| 久久精品亚洲日本佐佐木明希| 亚洲熟妇少妇任你躁在线观看无码 | 国产成人免费a在线资源| 黄在线观看www免费看|