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

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

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

    2006年11月23日

    http://www.firstui.com/read.php/250.htm

    posted @ 2006-11-23 23:47 killvin| 編輯 收藏

    2006年10月29日

    很久都已經(jīng)下定了決心不再維護那里的空間了,即使是成為了特約的作者也難以挽回我對他們Blog的信心,雖然blogjava的系統(tǒng)與csdn的是同樣出自一份代碼,但顯然無論從服務的內容還是代碼的理解上,csdn與blogjava相差的太遠,當然我并不是完全的贊同目前blogjava的風格,尤其是身為介紹java的博客系統(tǒng),竟然采用asp的技術來實現(xiàn),實在是太煞風景了,甚至有些讓你匪夷所思,不過瑕不掩瑜,畢竟無論從速, 專業(yè)程度還是目前提供的服務上來看,blogjava確實比同類型的網(wǎng)站要優(yōu)秀一些.

    posted @ 2006-10-29 15:54 killvin| 編輯 收藏

    2006年10月14日

    Version 1.01 on Bindows enhanced its Mozilla support considerably. At this point, the level of support is such that many complicated applications are available to Mozilla users. For example: now these can use our forum and the registration application.
    We are dedicated to make Bindows work at least as well with Mozilla 1.4+ as it does with Internet Explorer 6.0 SP1. The Mozilla support is now integral part of Bindows and we will continue to develop, maintain and support it.
    However, some issues are not solved yet and this document details them.


    Known Issues
    Web Services

    We do not yet have a working SOAP web service client working with Mozilla. Mozilla has a built in web service client but it does not yet work with all the major web services platforms. We anticipate this to be resolve in a near future version of Bindows.


    Graphs, Charts and Gauges
    Graphs, charts and gauges are not supported. For the Bindows charts and gauges we rely on VML to do the drawing. Mozilla does not yet have a way to draw vector graphics at the client side without using a plugin. We consider several alternatives here but there is no time frame for a solution yet.


    Miscellaneous
    The caret is sometimes not shown in a focused textfield. This is a Mozilla bug and unless this is fixed in Mozilla this issue will remain.
    Preferred size is not working consistently. Please report the cases where you are experiencing issues with the preferred size and we will see what can be done in those specific cases.
    Icons in menu items works inconsistently between Mozilla versions. This is due to differences in the Mozilla toolkits used by different browsers.
    Menu labels do not accept HTML. If you use HTML, the markup will be stripped.
    The rendering of the group box is incorrect.
    Labels with text align center and icon position set to top or bottom are a bit jumpy, ie. the icon move around depending on the state.
    Dragging elements sometimes inconsistent. If an image is dragged an OS level drag and drop is initiated. Also, for some components a dragging will not work when the mouse leaves the browser window or enters a frame.
    The upper border for the tab pages are not correctly drawn in Mozilla Firefox using Windows Classic. This is a Mozilla bug.
    BiKeyboardEvent keyCode is sometimes incorrect in a keypress event (for special keys). The reason for this bug is that Internet Explorer and Mozilla are handling keyboard events differently.
    Resize events are not fired on all BiComponents.
    Focus and blur events are inconsistent when using BiRichEdit.

    posted @ 2006-10-14 16:21 killvin| 編輯 收藏

    2006年9月13日

    Jsparse is a parse?to parse the schema file?with javascript.
    If you are interested in it, you can vist the url
    http://code.google.com/p/jsparse/ ?

    get source with svn
    svn checkout http://jsparse.googlecode.com/svn/trunk/ jsparse

    posted @ 2006-09-13 23:23 killvin| 編輯 收藏

    ACE中的Double Checked Locking 模式


    (作者:Douglas C. Schmidt ,by huihoo.org CORBA課題 Thzhang 譯 , Allen整理,制作)

    意圖

    無論什么時候當臨界區(qū)中的代碼僅僅需要加鎖一次,同時當其獲取鎖的時候必須是線程安全的,可以用Double Checked Locking 模式來減少競爭和加鎖載荷。

    動機

    1、標準的單例。開發(fā)正確的有效的并發(fā)應用是困難的。程序員必須學習新的技術(并發(fā)控制和防止死鎖的算法)和機制(如多線程和同步API)。此外,許多熟悉的設計模式(如單例和迭代子)在包含不使用任何并發(fā)上下文假設的順序程序中可以工作的很好。為了說明這點,考慮一個標準的單例模式在多線程環(huán)境下的實現(xiàn)。單例模式保證一個類僅有一個實例同時提供了全局唯一的訪問這個實例的入口點。在c++程序中動態(tài)分配單例對象是通用的方式,這是因為c++程序沒有很好的定義靜態(tài)全局對象的初始化次序,因此是不可移植的。而且,動態(tài)分配避免了單例對象在永遠沒有被使用情況下的初始化開銷。

    
    class Singleton
    {
    public:
    static Singleton *instance (void)
    {
    if (instance_ == 0)
    // Critical section.
    instance_ = new Singleton;
    return instance_;
    }
    void method (void);
    // Other methods and members omitted.
    private:
    static Singleton *instance_;
    };
    
    
    

    應用代碼在使用單例對象提供的操作前,通過調用靜態(tài)的instance方法來獲取單例對象的引用,如下所示:
    Singleton::instance ()->method ();
    2、問題:競爭條件。不幸的是,上面展示的標準單例模式的實現(xiàn)在搶先多任務和真正并行環(huán)境下無法正常工作。例如,如果在并行主機上運行的多個線程在單例對象初始化之前同時調用Singleton::instance方法,Singleton的構造函數(shù)將被調用多次,這是因為多個線程將在上面展示的臨界區(qū)中執(zhí)行new singleton操作。臨界區(qū)是一個必須遵守下列定式的指令序列:當一個線程/進程在臨界區(qū)中運行時,沒有其他任何線程/進程會同時在臨界區(qū)中運行。在這個例子中,單例的初始化過程是一個臨界區(qū),違反臨界區(qū)的原則,在最好的情況下將導致內存泄漏,最壞的情況下,如果初始化過程不是冪等的(idempotent.),將導致嚴重的后果。

    3、 通常的陷阱和弊端。實現(xiàn)臨界區(qū)的通常方法是在類中增加一個靜態(tài)的Mutex對象。這個Mutex保證單例的分配和初始化是原子操作,如下:

    
    class Singleton
    {
    public:
    static Singleton *instance (void)
    {
    // Constructor of guard acquires lock_ automatically.
    Guard guard (lock_);
    // Only one thread in the critical section at a time.
    if (instance_ == 0)
    instance_ = new Singleton;
    return instance_;
    // Destructor of guard releases lock_ automatically.
    }
    private:
    static Mutex lock_;
    static Singleton *instance_;
    };
    
    

    guard類使用了一個c++的習慣用法,當這個類的對象實例被創(chuàng)建時,它使用構造函數(shù)來自動獲取一個資源,當類對象離開一個區(qū)域時,使用析構器來自動釋放這個資源。通過使用guard,每一個對Singleton::instance方法的訪問將自動的獲取和釋放lock_。
    即使這個臨界區(qū)只是被使用了一次,但是每個對instance方法的調用都必須獲取和釋放lock_。雖然現(xiàn)在這個實現(xiàn)是線程安全的,但過多的加鎖負載是不能被接受的。一個明顯(雖然不正確)的優(yōu)化方法是將guard放在針對instance進行條件檢測的內部:

    
    static Singleton *instance (void)
    {
    if (instance_ == 0) {
    Guard guard (lock_);
    // Only come here if instance_ hasn't been initialized yet.
    instance_ = new Singleton;
    }
    return instance_;
    }
    
    
    這將減少加鎖負載,但是不能提供線程安全的初始化。在多線程的應用中,仍然存在競爭條件,將導致多次初始化instance_。例如,考慮兩個線程同時檢測 instance_ == 0,都將會成功,一個將通過guard獲取lock_另一個將被阻塞。當?shù)谝痪€程初始化Singleton后釋放lock_,被阻塞的線程將獲取lock_,錯誤的再次初始化Singleton。
    4、解決之道,Double Checked Locking優(yōu)化。解決這個問題更好的方法是使用Double Checked Locking。它是一種用于清除不必要加鎖過程的優(yōu)化模式。具有諷刺意味的是,它的實現(xiàn)幾乎和前面的方法一樣。通過在另一個條件檢測中包裝對new的調用來避免不必要的加鎖:

    
    class Singleton
    {
    public:
    static Singleton *instance (void)
    {
    // First check
    if (instance_ == 0)
    {
    // Ensure serialization (guard constructor acquires lock_).
    Guard guard (lock_);
    // Double check.
    if (instance_ == 0)
    instance_ = new Singleton;
    }
    return instance_;
    // guard destructor releases lock_.
    }
    private:
    static Mutex lock_;
    static Singleton *instance_;
    };
    
    

    第一個獲取lock_的線程將構建Singleton,并將指針分配給instance_,后續(xù)調用instance方法的線程將發(fā)現(xiàn)instance_ != 0,于是將跳過初始化過程。如果多個線程試圖并發(fā)初始化Singleton,第二個檢測件阻止競爭條件的發(fā)生。在上面的代碼中,這些線程將在lock_上排隊,當排隊的線程最終獲取lock_時,他們將發(fā)現(xiàn)instance_ != 0于是將跳過初始化過程。

    上面Singleton::instance的實現(xiàn)僅僅在Singleton首次被初始化時,如果有多個線程同時進入instance方法將導致加鎖負載。在后續(xù)對Singleton::instance的調用因為instance_ != 0而不會有加鎖和解鎖的負載。 通過增加一個mutex和一個二次條件檢測,標準的單例實現(xiàn)可以是線程安全的,同時不會產(chǎn)生過多的初始化加鎖負載。

    適應性

    > 當一個應用具有下列特征時,可以使用Double Checked Locking優(yōu)化模式:
    1、應用包含一個或多個需要順序執(zhí)行的臨界區(qū)代碼。
    2、多個線程可能潛在的試圖并發(fā)執(zhí)行臨界區(qū)。
    3、臨界區(qū)僅僅需要被執(zhí)行一次。
    4、在每一個對臨界區(qū)的訪問進行加鎖操作將導致過多加鎖負載。
    5、在一個鎖的范圍內增加一個輕量的,可靠的條件檢測是可行的。

    結構和參與者

    通過使用偽代碼能夠最好地展示Double Checked Locking模式的結構和參與者,圖1展示了在Double Checked Locking模式有下列參與者:



    1、僅有一次臨界區(qū)(Just Once Critical Section,)。臨界區(qū)所包含的代碼僅僅被執(zhí)行一次。例如,單例對象僅僅被初始化一次。這樣,執(zhí)行對new Singleton的調用(只有一次)相對于Singleton::instance方法的訪問將非常稀少。
    2、mutex。鎖被用來序列化對臨界區(qū)中代碼的訪問。
    3、標記。標記被用來指示臨界區(qū)的代碼是否已經(jīng)被執(zhí)行過。在上面的例子中單例指針instance_被用來作為標記。
    4、 應用線程。試圖執(zhí)行臨界區(qū)代碼的線程。

    協(xié)作

    圖2展示了Double Checked Locking模式的參與者之間的互動。作為一種普通的優(yōu)化用例,應用線程首先檢測flag是否已經(jīng)被設置。如果沒有被設置,mutex將被獲取。在持有這個鎖之后,應用線程將再次檢測flag是否被設置,實現(xiàn)Just Once Critical Section,設定flag為真。最后應用線程釋放鎖。



    結論

    使用Double Checked Locking模式帶來的幾點好處:
    1、最小化加鎖。通過實現(xiàn)兩個flag檢測,Double Checked Locking模式實現(xiàn)通常用例的優(yōu)化。一旦flag被設置,第一個檢測將保證后續(xù)的訪問不要加鎖操作。
    2、防止競爭條件。對flag的第二個檢測將保證臨界區(qū)中的事件僅實現(xiàn)一次。
    使用Double Checked Locking模式也將帶來一個缺點:產(chǎn)生微妙的移植bug的潛能。這個微妙的移植問題能夠導致致命的bug,如果使用Double Checked Locking模式的軟件被移植到?jīng)]有原子性的指針和正數(shù)賦值語義的硬件平臺上。例如,如果一個instance_指針被用來作為Singleton實現(xiàn)的flag,instance_指針中的所有位(bit)必須在一次操作中完成讀和寫。如果將new的結果寫入內存不是一個原子操作,其他的線程可能會試圖讀取一個不健全的指針,這將導致非法的內存訪問。
    在一些允許內存地址跨越對齊邊界的系統(tǒng)上這種現(xiàn)象是可能的,因此每次訪問需要從內存中取兩次。在這種情況下,系統(tǒng)可能使用分離的字對齊合成flag,來表示instance_指針。
    如果一個過于激進(aggressive)編譯器通過某種緩沖手段來優(yōu)化flag,或是移除了第二個flag==0檢測,將帶來另外的相關問題。后面會介紹如何使用volatile關鍵字來解決這個問題。

    實現(xiàn)和例子代碼

    ACE在多個庫組件中使用Double Checked Locking模式。例如,為了減少代碼的重復,ACE使用了一個可重用的適配器ACE Singleton來將普通的類轉換成具有單例行為的類。下面的代碼展示了如何用Double Checked Locking模式來實現(xiàn)ACE Singleton。

    
    // A Singleton Adapter: uses the Adapter
    // pattern to turn ordinary classes into
    // Singletons optimized with the
    // Double-Checked Locking pattern.
    template 
    class ACE_Singleton
    {
    public:
    static TYPE *instance (void);
    protected:
    static TYPE *instance_;
    static LOCK lock_;
    };
    template  TYPE *
    ACE_Singleton::instance ()
    {
    // Perform the Double-Checked Locking to
    // ensure proper initialization.
    if (instance_ == 0) {
    ACE_Guard lock (lock_);
    if (instance_ == 0)
    instance_ = new TYPE;
    }
    return instance_;
    }
    


    ACE Singleton類被TYPE和LOCK來參數(shù)化。因此一個給定TYEP的類將被轉換成使用LOCK類型的互斥量的具有單例行為的類。
    ACE中的Token Manager.是使用ACE Singleton的一個例子。Token Manager實現(xiàn)在多線程應用中對本地和遠端的token(一種遞歸鎖)死鎖檢測。為了減少資源的使用,Token Manager被按需創(chuàng)建。為了創(chuàng)建一個單例的Token Manager對象,只是需要實現(xiàn)下面的typedef:

    typedef ACE_Singleton Token_Mgr;
    Token Manager單例將被用于本地和遠端的token死鎖檢測。在一個線程阻塞等待互斥量之前,它首先查詢Token Manager單例,來測試阻塞是否會導致死鎖狀態(tài)。對于系統(tǒng)中的每一個token,Token Manager單例維護一個持有token線程和所有阻塞等待在該token的線程記錄鏈表。這些數(shù)據(jù)將提供充足的檢測死鎖狀態(tài)的依據(jù)。使用Token Manager單例的過程如下:

    
    // Acquire the mutex.
    int Mutex_Token::acquire (void)
    {
    // If the token is already held, we must block.
    if (mutex_in_use ()) {
    // Use the Token_Mgr Singleton to check
    // for a deadlock situation *before* blocking.
    if (Token_Mgr::instance ()->testdeadlock ()) {
    errno = EDEADLK;
    return -1;
    				}
    else
    // Sleep waiting for the lock...
    		// Acquire lock...
    		}
    

    變化

    一種變化的Double Checked Locking模式實現(xiàn)可能是需要的,如果一個編譯器通過某種緩沖方式優(yōu)化了flag。在這種情況下,緩沖的粘著性(coherency)將變成問題,如果拷貝flag到多個線程的寄存器中,會產(chǎn)生不一致現(xiàn)象。如果一個線程更改flag的值將不能反映在其他線程的對應拷貝中。

    另一個相關的問題是編譯器移除了第二個flag==0檢測,因為它對于持有高度優(yōu)化特性的編譯器來說是多余的。例如,下面的代碼在激進的編譯器下將被跳過對flag的讀取,而是假定instance_還是為0,因為它沒有被聲明為volatile的。
    
    Singleton *Singleton::instance (void)
    {
    if (Singleton::instance_ == 0)
    {
    // Only lock if instance_ isn't 0.
    Guard guard (lock_);
    // Dead code elimination may remove the next line.
    // Perform the Double-Check.
    if (Singleton::instance_ == 0)
    // ...
    
    


    解決這兩個問題的一個方法是生命flag為Singleton的volatile成員變量,如下:
    private:
    static volatile long Flag_; // Flag is volatile.
    使用volatile將保證編譯器不會將flag緩沖到編譯器,同時也不會優(yōu)化掉第二次讀操作。使用volatile關鍵字的言下之意是所有對flag的訪問是通過內存,而不是通過寄存器。

    相關模式

    Double Checked Locking模式是First-Time-In習慣用法的一個變化。First-Time-In習慣用法經(jīng)常使用在類似c這種缺少構造器的程序語言中,下面的代碼展示了這個模式:

    
    	static const int STACK_SIZE = 1000;
    static T *stack_;
    static int top_;
    void push (T *item)
    {
    // First-time-in flag
    if (stack_ == 0) {
    stack_ = malloc (STACK_SIZE * sizeof *stack);
    assert (stack_ != 0);
    top_ = 0;
    }
    stack_[top_++] = item;
    // ...
    }
    
    

    第一次push被調用時,stack_是0,這將導致觸發(fā)malloc來初始化它自己。

    posted @ 2006-09-13 23:16 killvin| 編輯 收藏

    2006年7月2日

    在上一篇的文章中,比較仔細的分析了IE對于Cookie處理過程中出現(xiàn)的問題,既然存在問題就要想辦法解決,而問題的關鍵在于IE沒有能夠"老實"的報告用戶對于Cookie的設置問題

    IE
    GET /mail HTTP/1.1
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
    Accept-Language: zh-cn
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Maxthon)
    Host: mail.google.com
    Connection: Keep-Alive
    Cookie:
    gmailchat=killvin.liu@gmail.com/519974 ; PREF=ID=d68c481e542af276:NW=1:TM=1151742225:LM=1151742225:S=2qbdhg0_z3i-OAbW; SID=DQAAAG8AAACEdcjD2IZMNqZVatDbD62X8_U18oJuTVQc9XZUJi7MgCkM8sggJ8M5npZ35GXjdalT2o8QWPUve04tepy61MPv4v_EpILafg3JdIf8AFjD91aMT0tI5gb763FouV3e_2-C364HDO5Qzb4P4gjjgpHC

    Firefox
    GET /mail HTTP/1.1
    Host: mail.google.com
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
    Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive

    我們可以注意到:如果用戶關閉了瀏覽器的Cookie選項,在Firefox中對于新的請求是包含Cookie的信息的,然而IE卻恰恰相反!這也就直接用IE瀏覽一些網(wǎng)站所導致的Cookie校驗失敗問題(比如即使用戶在使用過程中突然關閉Cookie,依然可以自由的訪問網(wǎng)站的各項服務),進一步,如果某個網(wǎng)站是讀取依靠Cookie中的信息來驗證用戶(尤其是那種保存客戶信息的提示),即使這個用戶離開或者關閉窗口,任何一個后來的人都可以輕松的瀏覽這個用戶的私有信息!這就是Cookie的最大的問題所在,當然這是另外的話題,不屬于本次討論的范疇,這一次要說的是
    如何避免IE瀏覽器下,用戶關閉Cookie的問題。

    有一個思路,經(jīng)過測試我們發(fā)現(xiàn)IE瀏覽器只是在首次頁面請求的時候才會去讀取Cookie的值,所以,為了避免IE瀏覽器關閉Cookie的問題,可以在用戶請求某個鏈接的時候,先將用戶的Cookie存放在某處,并清空此時所有的Cookie值,再次的請求頁面,而這樣做的目的就是強迫IE讀取硬盤上的Cookie,如果此時用戶關閉了Cookie,就不會在請求的頭信息中看到Cookie信息;如果沒有關閉Cookie,就可以放心的將原先的Cookie寫回Reponse對象。


    只是不知道Google的網(wǎng)站是否也是按照這個思路去解決此問題的?

    posted @ 2006-07-02 21:53 killvin| 編輯 收藏

    2006年7月1日

    IE在處理COOKIE方面的問題

    1。即使你提高了瀏覽器的隱私登記,在第一次打開窗口的時候,你獲取不到任何的Cookies對象(很顯然的結果),然而當你再次刷新本頁面的,Cookie此時會奇跡般的出現(xiàn)!而在Firefox瀏覽器中按照以上的步驟,是不會出現(xiàn)這樣的情況的。

    2。不僅如此,你還可以透過Action的處理,多次的往Cookie中增加Cookie的數(shù)量(當然在Action中你依然可以自由的獲取到Cookie這個數(shù)組,并且不為空),然而讓人匪夷所思的是在Cookie的存放目錄下你是找尋不到任何的蛛絲馬跡的。而在Firefox沒有出現(xiàn)以上的情況。

    -解決
    1。在首次進入頁面時查詢客戶端的Cookie,如果不存在則警告用戶,并要求再次的登陸。
    2。在用戶登陸后,如果更改了瀏覽器的隱私級別,對于Firefox標準的瀏覽器,此時肯定不會再找到Cookie數(shù)組對象了,你需要做的僅僅只是將頁面調轉到登陸窗口;而在IE下就非常的麻煩了甚至無法解決,因為你依然可以訪問到原來的Cookie數(shù)組值,(比如,用IE在CSDN登陸后提高隱私級別,你依然可以登陸到其他的服務區(qū)域)此時沒有什么好的辦法,不過Google解決了這樣的問題,只是不知道如何解決的。



    IE在處理Frame標記的問題
    1。如果你在某個頁面中嵌入了Frame標簽,并且希望與這個嵌入的頁面共享某些存放在Session中的數(shù)據(jù),此時你需要將外部的sessionId傳入到frame標記的頁面中。然而在IE中你可能并不能完全的享受這樣的邏輯,原因在于IE對于嵌入的頁面不會自動的傳遞sessionId,也許你碰巧可以,也許不行,也就是說完全是在IE的"掌控"之下。而在Firefox沒有出現(xiàn)這樣的情況。

    -解決
    為嵌入的頁面中所有的鏈接增加sessionId參數(shù)。


    最好的辦法就是:說服客戶使用標準的瀏覽器Firefox!

    posted @ 2006-07-01 15:53 killvin| 編輯 收藏

    2006年6月27日

    在Struts中我們經(jīng)常這樣循環(huán)的打印Message
    <logic:messagesPresent message="true">
    ? <html:messages id="msg" message="true">
    ??? <div class="success">
    ????? <bean:write name="msg"/>
    ??? </div><br/>
    ? </html:messages>
    </logic:messagesPresent>

    查閱struts tag的文檔我們看到了關于messagesPresent的message屬性注釋如下

    message

    By default the tag will retrieve the request scope bean it will iterate over from the Globals.ERROR_KEY constant string, but if this attribute is set to 'true' the request scope bean will be retrieved from the Globals.MESSAGE_KEY constant string. Also if this is set to 'true', any value assigned to the name attribute will be ignored


    也就是說在將message設置為true時,會去request中尋找Globals.MESSAGE_KEY所代表的bean,然而我們在具體的Action使用ActionMessages類的時候往往是這樣的
    ActionMessages messages = getErrors(request);
    messages.add(ActionMessages.GLOBAL_MESSAGE , new ActionMessage(key , value0));
    saveMessages(request,messages);

    而往往困擾人的就在于為什么要給messages中放入名稱為"ActionMessages.GLOBAL_MESSAGE"的ActionMessage對象,而且還需要再次的調用saveErrors(request,messages)方法?

    首先要說明的是你為ActionMessage起任何的名稱都沒有關系,因為ActionMessages本身維持著一個HashMap,而參數(shù)property就是這個HashMap中的key值,如果不存在則會建立相應的key,并將需要保存的ActionMessage對象存入到這個key所對應的List中。
    ??? public void add(String property, ActionMessage message) {

    ??????? ActionMessageItem item = (ActionMessageItem) messages.get(property);
    ??????? List list = null;

    ??????? if (item == null) {
    ??????????? list = new ArrayList();
    ??????????? item = new ActionMessageItem(list, iCount++, property);

    ??????????? messages.put(property, item);
    ??????? } else {
    ??????????? list = item.getList();
    ??????? }

    ??????? list.add(message);

    ??? }

    至于為什么一定要調用saveMessages(request,messages)?看看它具體的實現(xiàn)邏輯就清楚了
    ??? protected void saveMessages(
    ??????? HttpServletRequest request,
    ??????? ActionMessages messages) {

    ??????? // Remove any messages attribute if none are required
    ??????? if ((messages == null) || messages.isEmpty()) {
    ??????????? request.removeAttribute(Globals.MESSAGE_KEY);
    ??????????? return;
    ??????? }

    ??????? // Save the messages we need
    ??????? request.setAttribute(Globals.MESSAGE_KEY, messages);
    ??? }

    再對比前面介紹的messagesPresent標簽的使用,是不是就清楚了呢?原來它是將ActionMessages對象保存在request中,并且名稱是Globals.ERROR_KEY!從而為tag的順利解析鋪平了道路。當然按理你可以選擇將這樣的對象放置在任何的scope中,但Action只是提供了request , session兩種Scope(不過page , application不經(jīng)常使用,可以理解,但不提供相應的結構就不太好了)

    至于messagesPresent標簽是如何在scope中尋找ActionMessages對象

    org.apache.struts.taglib.logic.MessagesPresentTag
    ??? protected boolean condition(boolean desired) throws JspException {
    ??????? ActionMessages am = null;

    ??????? String key = name;
    ??????? if (message != null && "true".equalsIgnoreCase(message)){
    ?????????? key = Globals.MESSAGE_KEY;
    ??????? }

    ??????? try {
    ??????????? am = TagUtils.getInstance().getActionMessages(pageContext, key);
    ???????????
    ??????? } catch (JspException e) {
    ??????????? TagUtils.getInstance().saveException(pageContext, e);
    ??????????? throw e;
    ??????? }

    ??????? Iterator iterator = (property == null) ? am.get() : am.get(property);

    ??????? return (iterator.hasNext() == desired);

    ??? }

    org.apache.struts.taglib.TagUtils
    ?? public ActionErrors getActionErrors(PageContext pageContext, String paramName)
    ??????????? throws JspException {

    ??????? ActionErrors errors = new ActionErrors();

    ??????? Object value = pageContext.findAttribute(paramName);
    ??????? if (value != null) {
    ??????????? try {
    ??????????????? if (value instanceof String) {
    ??????????????????? errors.add(
    ??????????????????????????? ActionMessages.GLOBAL_MESSAGE,
    ??????????????????????????? new ActionMessage((String) value));

    ??????????????? } else if (value instanceof String[]) {
    ??????????????????? String keys[] = (String[]) value;
    ??????????????????? for (int i = 0; i < keys.length; i++) {
    ??????????????????????? errors.add(
    ??????????????????????????????? ActionMessages.GLOBAL_MESSAGE,
    ??????????????????????????????? new ActionMessage(keys[i]));
    ??????????????????? }

    ??????????????? } else if (value instanceof ActionErrors) {
    ??????????????????? errors = (ActionErrors) value;

    ??????????????? } else {
    ??????????????????? throw new JspException(
    ??????????????????????????? messages.getMessage(
    ??????????????????????????????????? "actionErrors.errors",
    ??????????????????????????????????? value.getClass().getName()));
    ??????????????? }

    ??????????? } catch (JspException e) {
    ??????????????? throw e;

    ??????????? } catch (Exception e) {
    ??????????????? log.debug(e, e);
    ??????????? }
    ??????? }
    ??????? return errors;
    ??? }

    PageContext中的findAttribute會幫你在scope中尋找名稱為Globals.MESSAGE_KEY的ActionMessage對象。


    注意
    雖然Struts已經(jīng)聲明:不推薦使用ActionErrors & ActionError對象,但在一些遺留的系統(tǒng)中,依然還是可以看到其影子,所以如果你的系統(tǒng)不幸屬于這樣的兩種混合系統(tǒng),有以下的幾種方法可以參考
    1。兩次調用messagesPresent,如下
    <!-- Print ActionErrors Object -->
    <logic:messagesPresent>
    ? <html:messages id="msg" message="true">
    ??? <div class="success">
    ????? <bean:write name="msg"/>
    ??? </div><br/>
    ? </html:messages>
    </logic:messagesPresent>

    <!-- Print ActionMessages Object -->
    <logic:messagesPresent message="true">
    ? <html:messages id="msg" message="true">
    ??? <div class="success">
    ????? <bean:write name="msg"/>
    ??? </div><br/>
    ? </html:messages>
    </logic:messagesPresent>

    2.分別使用<html:messages> <html:errors>標簽,當然在老系統(tǒng)中需要調用Action的saveErrors方法,而在新的應用中要調用saveMessages方法。

    3.更換所有的ActionErrors為ActionMessages,并將所有調用saveErrors的地方更換成saveMessages,并將<html:errors>標簽相應的更換成<html:messages message="true"> - 推薦!

    ?

    posted @ 2006-06-27 23:02 killvin| 編輯 收藏

    2006年4月6日

    第2章 并發(fā)問題及控制手段

    什么是并發(fā)問題?假設有這么一家書吧,顧客可以到那里喝茶讀書。顧客拿著選好要讀的圖書到柜臺登記,然后找個地方去閱讀,臨走時將圖書歸還店家。有一天,一個顧客相中了一本書后正要拿去登記,另一個顧客的手也抓住了這僅有的一本書,并發(fā)問題出現(xiàn)了。兩個顧客要讀同一本書,互不相讓,這讓店主傷透了腦筋。這個案例僅僅是眾多并發(fā)問題中的一個微小部分,但從中我們可以看出并發(fā)問題主要出現(xiàn)在多個用戶對有限資源進行訪問的時候,如果解決不好會直接影響系統(tǒng)的有效、正常運行。數(shù)據(jù)庫是一個共享的資源,并發(fā)問題的出現(xiàn)是必不可免的,如何識別并發(fā)類型并加以控制是這一章重點要講述的內容。

    本章將分成兩大部分,一部分主要講Visual FoxPro中并發(fā)控制機制。VFP中并發(fā)控制相對簡單,數(shù)據(jù)加鎖的形式比較單一,非常適合作為初步了解并發(fā)問題的切入點。第二部分以SQL Server 2000、ADO.NET以及C#為主要工具,深入了解并發(fā)一致性問題、封鎖協(xié)議、事務隔離等內容,難度相對較深。象一些更為深入的并發(fā)控制手段,例如多粒度封鎖和意象鎖等內容在本章中將不做深入討論,感興趣可以參考相關書籍。

    ?

    [實在不好意思COPY別人的成果,不過這篇文章出奇的精彩,將并發(fā)操作的來龍去脈說的清清楚楚,也是我正要找的,比JAVAEYE上面所謂的專家叫嚷著什么"悲觀鎖"、"樂觀鎖"而不解是原因要強的多!值得收藏]

    posted @ 2006-04-06 10:57 killvin| 編輯 收藏

    2006年4月1日

    痛快!。。。人們總是認為罵人是沒有素質的象征,然而我到覺得要看對誰而言,如果你的面前是個謙虛、嚴謹而又懂得尊重別人的人,你根本就不可能讓自己憤怒,也不可能讓自己表現(xiàn)的很沒有素質;相反如果你的面前是個先入為主、自傲、不懂得尊重別人的人,你的憤怒就會在最短的時間內激發(fā)出來。-對于小人,就要罵!

    而這有與北大青鳥有什么關系呢?

    在我的職業(yè)生涯里,有一段讓自己憤怒的培訓經(jīng)歷,到今天我都為自己在這樣的培訓部的學習經(jīng)歷而感到恥辱!甚至不愿意在簡歷里提及ACCP的字樣,而這樣的培訓經(jīng)歷就是在北大青鳥(西安兆隆)里度過的。

    我參加的是北大青鳥(西安兆隆)的第二期培訓,培訓的課程涉及到數(shù)據(jù)庫、編程語言、職業(yè)素質、項目實踐等,看上去非常的正規(guī),可是真正的學習效果卻是讓人非常的失望的!

    首先,就是它的課程體系,完全的引入印度的教程,而翻譯的質量非常的差,其實這到?jīng)]有什么,只是教程的講解范圍和深度都非常的淺(這還是第二期的培訓),如果你只是按照它的教程我可以說你根本學不到任何有價值的東西,只是皮毛而已。-拿著淡薄的教學資料的同時你也就上了賊船了。


    再次,就是它的老師的水平實在不敢恭維,(當然并不是說根本就沒有好的老師,曾經(jīng)就遇到過一個講解JAVA與UML的老師,水平非常的高深,可惜ACCP沒有留住),比如編程語言中學習了VB,僅僅只是這一門課程就換了3個老師,最后是一位號稱是西工大的博士上的課,然而這位博士顯然是心思不再這里,除了講解課本上已經(jīng)有的代碼,根本不敢深入的講解原理,這門課程也就這樣混過去了。-如果這樣學習編程語言道不如自學來得輕松。


    還有,就是所謂的項目實踐根本就不是老師帶的項目,而是一些書本上或者捏造出來的一些項目,比如圖書管理系統(tǒng)等,如果學員無法真正的理解需求,怎么去理解設計,又如何來進行實際的編碼呢?如果遇到圖書管理的專業(yè)問題來問誰呢?-別指望在他們宣傳的所謂的項目實踐中得到鍛煉。

    在看看他們引以為傲的工作分配問題吧?就我個人的親身感受來言,這里會提供一些工作的機會,但都是一些小公司,而且往往是一些前三個月不給工資的公司;當時我在我們班級里是比較認真的一個(我是班里唯一的一個交了對項目分析文檔的學員,并且是項目實踐中的小組組長),可是在一次很好的面試機會面前,她們竟然由于工作的失誤忘記了給我打電話?!-如果這樣的工作分配策略也算作是給予你的答案的話,你一定會變得和我一樣的憤怒!


    我沒有在ACCP學到任何的有用的東西,然而在真實的世界里卻學到了人們對于ACCP的看法,很多的技術經(jīng)理 、 技術總監(jiān)從骨子里非常的厭惡從北大青鳥出來的學生,對于他們開設的一些課程也是相當?shù)姆锤校敃r在西部世紀工作的時候,同組的就有和我一起上課的同班同學,在他交了8000多元的學習費用(總共的費用接近1萬多元)后,得到的僅僅只是西部世紀的一張試用通知單,而條件是必須無條件的為公司工作三個月!


    這就是我在北大青鳥的學習經(jīng)歷,然而憤怒的不是這個,卻是今天參加的面試經(jīng)歷,對照著自己的個人的工作經(jīng)歷我希望自己能夠成為一名培訓部的老師,教給那些原來如我一樣的學生一些在實踐當中有用的東西,而不是空洞的理論!所以我給ACCP投了自己的簡歷,然而讓我卻又一次的遇到了那個欺騙過我的咨詢師,不過她的記憶力也是非常的好,一眼就認出了我(當然了我是曾經(jīng)給她帶來獎金的人),在緊接著的面試過程中已經(jīng)變了味道,談論的話題也不是具體項目技術的問題,(不是我笑話她與她談論技術問題根本就如同對牛彈琴)她顯然是一個沒有素質的WOMAN,也可以肯定的是她根本沒有在外企工作過的經(jīng)歷,所以說話的詞匯以及與其如同大街上的潑婦一般,可以想見她一定是一個被ACCP嚴重洗過腦的人,而且是屬于那種技術失敗的產(chǎn)品,她無法接受別的培訓部的名字,一旦你提起別的培訓部的某個老師的水平如何如何的好,她就如同一個快被點燃的鞭炮一般,兩眼充滿了憤怒!

    然而讓我最終和她一般的沒有素質的大罵的是她對于我辭職的評點,我很納悶的是她在不知道一件事情的原因的情況下,可以講述自己的觀點!并且是帶著教育的口吻,實在是人才呀!這就是北大青鳥的"人才力量",對于這樣的白癡級別的任務的觀點,我只好打斷,因為它甚至連我在的那個單位的名字都不知道!!

    實在是一場鬧劇,而她更像是個小丑,除了唧唧喳喳的重復一些"洗腦"的詞匯已經(jīng)不知道窗外的天氣了,可以預料北大青鳥的牌子必將會毀在這些個白癡的手中,世界需要白癡,那如同鮮花需要牛糞一樣,我們改變不了白癡的世界觀的,你能夠做的就是別被這臭烘烘的牛糞給熏臭了。

    posted @ 2006-04-01 12:53 killvin| 編輯 收藏

    僅列出標題  下一頁
    主站蜘蛛池模板: 国产亚洲3p无码一区二区| 亚洲一区二区三区国产精品| 亚洲第一成年男人的天堂| 国产精品永久免费| 亚洲中文字幕成人在线| 特a级免费高清黄色片| 亚洲欧洲日本在线| a毛片在线免费观看| 亚洲2022国产成人精品无码区| 日本免费一区二区三区| 亚洲午夜国产精品| 免费视频淫片aa毛片| 国产午夜亚洲精品不卡| 精品亚洲一区二区三区在线播放 | 亚洲国产综合精品中文第一区| 99久9在线|免费| 成人区精品一区二区不卡亚洲| 国产最新凸凹视频免费| 五月婷婷免费视频| 亚洲av无码片在线播放| 1024免费福利永久观看网站| 亚洲妇女无套内射精| 亚洲欧洲日本在线| 69国产精品视频免费| 亚洲熟妇久久精品| 久久夜色精品国产亚洲av | 免费国产成人高清在线观看网站| 亚洲精品自偷自拍无码| 精品国产香蕉伊思人在线在线亚洲一区二区 | 911精品国产亚洲日本美国韩国| 日本精品人妻无码免费大全| 无码色偷偷亚洲国内自拍| 亚洲国产一二三精品无码| 国产91色综合久久免费分享| 最新亚洲人成无码网站| 亚洲成A∨人片在线观看不卡| 又粗又大又黑又长的免费视频| 国产亚洲高清在线精品不卡| 亚洲AV成人无码久久精品老人| 午夜精品在线免费观看| a在线观看免费网址大全|