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

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

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

    2006年6月27日

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

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

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

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

    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| 編輯 收藏

    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整理,制作)

    意圖

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

    動(dòng)機(jī)

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

    
    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_;
    };
    
    
    

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

    3、 通常的陷阱和弊端。實(shí)現(xiàn)臨界區(qū)的通常方法是在類中增加一個(gè)靜態(tài)的Mutex對(duì)象。這個(gè)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類使用了一個(gè)c++的習(xí)慣用法,當(dāng)這個(gè)類的對(duì)象實(shí)例被創(chuàng)建時(shí),它使用構(gòu)造函數(shù)來自動(dòng)獲取一個(gè)資源,當(dāng)類對(duì)象離開一個(gè)區(qū)域時(shí),使用析構(gòu)器來自動(dòng)釋放這個(gè)資源。通過使用guard,每一個(gè)對(duì)Singleton::instance方法的訪問將自動(dòng)的獲取和釋放lock_。
    即使這個(gè)臨界區(qū)只是被使用了一次,但是每個(gè)對(duì)instance方法的調(diào)用都必須獲取和釋放lock_。雖然現(xiàn)在這個(gè)實(shí)現(xiàn)是線程安全的,但過多的加鎖負(fù)載是不能被接受的。一個(gè)明顯(雖然不正確)的優(yōu)化方法是將guard放在針對(duì)instance進(jìn)行條件檢測(cè)的內(nèi)部:

    
    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_;
    }
    
    
    這將減少加鎖負(fù)載,但是不能提供線程安全的初始化。在多線程的應(yīng)用中,仍然存在競(jìng)爭(zhēng)條件,將導(dǎo)致多次初始化instance_。例如,考慮兩個(gè)線程同時(shí)檢測(cè) instance_ == 0,都將會(huì)成功,一個(gè)將通過guard獲取lock_另一個(gè)將被阻塞。當(dāng)?shù)谝痪€程初始化Singleton后釋放lock_,被阻塞的線程將獲取lock_,錯(cuò)誤的再次初始化Singleton。
    4、解決之道,Double Checked Locking優(yōu)化。解決這個(gè)問題更好的方法是使用Double Checked Locking。它是一種用于清除不必要加鎖過程的優(yōu)化模式。具有諷刺意味的是,它的實(shí)現(xiàn)幾乎和前面的方法一樣。通過在另一個(gè)條件檢測(cè)中包裝對(duì)new的調(diào)用來避免不必要的加鎖:

    
    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_;
    };
    
    

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

    上面Singleton::instance的實(shí)現(xiàn)僅僅在Singleton首次被初始化時(shí),如果有多個(gè)線程同時(shí)進(jìn)入instance方法將導(dǎo)致加鎖負(fù)載。在后續(xù)對(duì)Singleton::instance的調(diào)用因?yàn)閕nstance_ != 0而不會(huì)有加鎖和解鎖的負(fù)載。 通過增加一個(gè)mutex和一個(gè)二次條件檢測(cè),標(biāo)準(zhǔn)的單例實(shí)現(xiàn)可以是線程安全的,同時(shí)不會(huì)產(chǎn)生過多的初始化加鎖負(fù)載。

    適應(yīng)性

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

    結(jié)構(gòu)和參與者

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



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

    協(xié)作

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



    結(jié)論

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

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

    ACE在多個(gè)庫(kù)組件中使用Double Checked Locking模式。例如,為了減少代碼的重復(fù),ACE使用了一個(gè)可重用的適配器ACE Singleton來將普通的類轉(zhuǎn)換成具有單例行為的類。下面的代碼展示了如何用Double Checked Locking模式來實(shí)現(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ù)化。因此一個(gè)給定TYEP的類將被轉(zhuǎn)換成使用LOCK類型的互斥量的具有單例行為的類。
    ACE中的Token Manager.是使用ACE Singleton的一個(gè)例子。Token Manager實(shí)現(xiàn)在多線程應(yīng)用中對(duì)本地和遠(yuǎn)端的token(一種遞歸鎖)死鎖檢測(cè)。為了減少資源的使用,Token Manager被按需創(chuàng)建。為了創(chuàng)建一個(gè)單例的Token Manager對(duì)象,只是需要實(shí)現(xiàn)下面的typedef:

    typedef ACE_Singleton Token_Mgr;
    Token Manager單例將被用于本地和遠(yuǎn)端的token死鎖檢測(cè)。在一個(gè)線程阻塞等待互斥量之前,它首先查詢Token Manager單例,來測(cè)試阻塞是否會(huì)導(dǎo)致死鎖狀態(tài)。對(duì)于系統(tǒng)中的每一個(gè)token,Token Manager單例維護(hù)一個(gè)持有token線程和所有阻塞等待在該token的線程記錄鏈表。這些數(shù)據(jù)將提供充足的檢測(cè)死鎖狀態(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模式實(shí)現(xiàn)可能是需要的,如果一個(gè)編譯器通過某種緩沖方式優(yōu)化了flag。在這種情況下,緩沖的粘著性(coherency)將變成問題,如果拷貝flag到多個(gè)線程的寄存器中,會(huì)產(chǎn)生不一致現(xiàn)象。如果一個(gè)線程更改flag的值將不能反映在其他線程的對(duì)應(yīng)拷貝中。

    另一個(gè)相關(guān)的問題是編譯器移除了第二個(gè)flag==0檢測(cè),因?yàn)樗鼘?duì)于持有高度優(yōu)化特性的編譯器來說是多余的。例如,下面的代碼在激進(jìn)的編譯器下將被跳過對(duì)flag的讀取,而是假定instance_還是為0,因?yàn)樗鼪]有被聲明為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)
    // ...
    
    


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

    相關(guān)模式

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

    
    	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被調(diào)用時(shí),stack_是0,這將導(dǎo)致觸發(fā)malloc來初始化它自己。

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

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

    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

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

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


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

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

    IE在處理COOKIE方面的問題

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

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

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



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

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


    最好的辦法就是:說服客戶使用標(biāo)準(zhǔn)的瀏覽器Firefox!

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

    在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的文檔我們看到了關(guān)于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設(shè)置為true時(shí),會(huì)去request中尋找Globals.MESSAGE_KEY所代表的bean,然而我們?cè)诰唧w的Action使用ActionMessages類的時(shí)候往往是這樣的
    ActionMessages messages = getErrors(request);
    messages.add(ActionMessages.GLOBAL_MESSAGE , new ActionMessage(key , value0));
    saveMessages(request,messages);

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

    首先要說明的是你為ActionMessage起任何的名稱都沒有關(guān)系,因?yàn)锳ctionMessages本身維持著一個(gè)HashMap,而參數(shù)property就是這個(gè)HashMap中的key值,如果不存在則會(huì)建立相應(yīng)的key,并將需要保存的ActionMessage對(duì)象存入到這個(gè)key所對(duì)應(yīng)的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);

    ??? }

    至于為什么一定要調(diào)用saveMessages(request,messages)?看看它具體的實(shí)現(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);
    ??? }

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

    至于messagesPresent標(biāo)簽是如何在scope中尋找ActionMessages對(duì)象

    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會(huì)幫你在scope中尋找名稱為Globals.MESSAGE_KEY的ActionMessage對(duì)象。


    注意
    雖然Struts已經(jīng)聲明:不推薦使用ActionErrors & ActionError對(duì)象,但在一些遺留的系統(tǒng)中,依然還是可以看到其影子,所以如果你的系統(tǒng)不幸屬于這樣的兩種混合系統(tǒng),有以下的幾種方法可以參考
    1。兩次調(diào)用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>標(biāo)簽,當(dāng)然在老系統(tǒng)中需要調(diào)用Action的saveErrors方法,而在新的應(yīng)用中要調(diào)用saveMessages方法。

    3.更換所有的ActionErrors為ActionMessages,并將所有調(diào)用saveErrors的地方更換成saveMessages,并將<html:errors>標(biāo)簽相應(yīng)的更換成<html:messages message="true"> - 推薦!

    ?

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

    主站蜘蛛池模板: 亚洲AV中文无码乱人伦下载| 亚洲精品综合久久| 亚洲日本va在线观看| 色欲国产麻豆一精品一AV一免费| 中文亚洲AV片在线观看不卡| 一级毛片a女人刺激视频免费| 四虎永久在线精品免费观看地址| 视频一区二区三区免费观看| 亚洲成AV人网址| 中国国语毛片免费观看视频| 亚洲色爱图小说专区| 99在线在线视频免费视频观看| 亚洲黄色在线观看网站| 日韩欧毛片免费视频| 亚洲av午夜国产精品无码中文字 | 成视频年人黄网站免费视频| 亚洲伊人久久大香线焦| 成人五级毛片免费播放| 尤物视频在线免费观看| 国产亚洲精品免费视频播放| 久久WWW免费人成—看片| 亚洲午夜久久影院| 成年女人视频网站免费m| 免费无遮挡无遮羞在线看| 亚洲精品无码av人在线观看| 3d动漫精品啪啪一区二区免费| 亚洲欧洲日本在线观看| 免费一看一级毛片全播放| 国产午夜不卡AV免费| 亚洲人成电影青青在线播放| 国产免费黄色大片| 人人玩人人添人人澡免费| 亚洲人成伊人成综合网久久| 四虎影视永久免费观看| 无码av免费一区二区三区| 亚洲人片在线观看天堂无码| 爱情岛论坛网亚洲品质自拍| 久草免费在线观看视频| 深夜免费在线视频| 亚洲一级毛片视频| 亚洲热妇无码AV在线播放|