海水正藍

          面朝大海,春暖花開
          posts - 145, comments - 29, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          工作流管理聯盟:

          定義:

          創建并完善了工作流的相關標準,開拓了相關市場,是唯一的致力于工作流標準化的專業組織。該組織推出了工作流XMLWf-XML)和XML過程定義語言(XPDL) ,現在有超過80種有名的解決方案中使用了這兩種語言來存儲和交換過程模型。發布了用于工作流管理系統之間互操作的工作流參考模型,并且為了實現不同工作流產品之間的互操作,WfMC在工作流管理系統的相關術語、體系結構及應用編程接口等方面制定了一系列標準

           

          工作流:

          定義:

          工作流是一類能夠完全或者部分自動執行的經營過程,根據一系列過程規則,文檔、信息或任務能夠在不同的執行者之間傳遞、執行。從工作流的定義可以看出:(1)、有多個參與者:(2)、按照一定的規則進行活動(傳遞文檔、信息、任務等)(3)、活動的推進是自動的或部分自動的?!竟ぷ髁鞴芾砺撁恕?/span>

           

          工作流管理系統:

          定義:

          工作流管理系統是一個軟件系統,它負責工作流的定義和管理,并按照在計算機中預先定義好的工作流邏輯推進過程實例的執行。工作流管理系統(Workflow Management System,WFMS)是通過對工作流程中涉及各步驟的人員和IT資 源的合理調整,從而起到對工作流的定義、管理和實現的確定性作用。工作流管理系統是支持企業實現業務過程管理和自動化的強有力的軟件工具,它能完成工作流 的定義和管理,并按照在計算機中預先定義好的工作流邏輯推進工作流實例的執行。所以工作流是工作流管理系統的最重要的被管理的元素,就像表、試圖是數據庫 管理系統的管理對象一樣。【工作流管理聯盟】

           

          工作流參考模型:

          定義:

          1.通用的工作流系統實現模型

          2.把工作流系統中的主要功能組件和這些組件間的接口一起看成抽象的模型

           

          作用:

          1.這個模型可以與市場上的大多數產品相匹配,因此為開發協同工作的工作流系統奠定了基礎

          2.工作流參考模型的引入為人們討論工作流技術提供了一一個規范的術語表,為在一般意義上討論工作流系統的體系結構提供了基礎:工作流參考模型為工作流管理系統的關鍵軟件部件提供了功能描述,并描述了關鍵軟件部件交互,而

          且這個描述是獨立于特定產品或技術的實現的:從功能的角度定義五個關鍵軟件部件的交互接口,推動了信息交換的標準化,使得不同產品間的互操作成為可能。

           

          組成:

          1.軟件組件:為工作流系統的各種功能提供支持。

          2.各中類型的系統定義數據和控制數據:系統中的一個或多個軟件構件使用的數據。

          3.應用程序與應用程序數據庫:外部系統或數據,被系統調用來完成整個或部分工作流管理的功能。

           

          五類接口(WorkflowAPIWAPI)

          接口l:工作流執行服務與工作流建模工具間的接口,為實現對工作流過程定義的訪問(如建立、修改、刪除等)提供了一致的方法。

          接口2:工作流服務和用戶應用之間的接口,這是最主要的接口規范,它約定所有客戶方應用和工作流服務之間的功能訪問方式。

          接口3:工作流引擎和應用服務間的直接接口,其目標是集成工作流和其它應用服務而無需考慮原有工作流管理系統。

          接口4:工作流管理系統之間的互操作接口,用于描述不同工作流產品的互操作性。

          一般必須的互操作有兩個主要方面:

          (1)流程定義或子集的公共解釋;

          (2)運行時間對各種控制信息轉換,和在不同實施服務之間傳遞工作流相關數據和應用數據的支持。_個工作流引擎可以選擇、實例化和執行其他工作流引擎所約定的流程定義。

          接口5:工作流服務和工作流管理工具之間的接口,用于系統管理、應用訪問工作流執行服務。

           

          通用工作流系統各部分功能:

          1.工作流執行服務

          工作流執行服務是指由一個或者多個工作流引擎組成,以創建,管理和執行工作流實例,應用程序可能通過工作流應用程序接口(WAPI))與這個服務進行交互。工作流執行服務的主要功能是:解釋流程定義,生成過程實例,并管理其實施過程;依據工作流相關數據實現流程活動導航,包括順序或并行操作、期限設置等;與外部資源交互,完成各項活動;維護工作流控制數據和工作流相關數據,并向用戶傳送必要的相關數據。

               工作流執行服務使用外部資源的兩種途徑:

               1.用戶應用接口:工作流引擎通過任務項列表管理資源,任務項列表管理器負責從任務項列表中選擇并監督工作項的完成。任務項列表管理器或用戶負責調用應用工具。

               2.直接調用應用接口:工作流引擎直接調用相應的應用來完成一項任務。這主要是針對基于服務器的無需用戶參與的應用,那些需要用戶操作的活動則通過任務列表管理器來調用。

           

          2.工作流引擎

          工作流引擎是指為工作流實例提供運行時執行環境的軟件服務或引擎。 主要提供以下功能:對過程定義進行解釋;控制過程實例的生成、激活、掛起、終止等;控制過程活動間的轉換,包括串行或并行的操作、工作流相關數據的解釋 等;支持用戶操作的界面;維護工作流控制數據和工作流相關數據,在應用或用戶間傳遞工作流相關數據;提供用于激活外部應用并提供工作流相關數據的界面;提 供控制、管理和監督的功能。

           

          3.過程定義工具

          過程定義工具是管理流程定義的工具,它可以通過圖形方式把復雜的流程定義顯示出來并加以操作。流程定義工具同工作流執行服務交互,為用戶提供一種對實際業務過程進行分析、建模的手段,并生成業務過程的可被計算機處理的形式化描述(過程定義)。這也是工作流系統建立階段的主要任務。不同的工作流產品,其建模工具輸出格式是不同的。接口l不僅使工作流的定義階段和運行階段分離,使用戶可以分別選擇建模工具和執行產品,并且提供了對工作流過程進行協同定義的潛在能力,這些產品提供了分布的運行服務。

           

          4.管理和監控工具

          管理和監控工具主要負責對組織機構、角色等數據的維護管理和工作流實例的運行進行監控。管理員可以通過工作流管理工具獲得目前各個活動的運行情況報告,并可干預實例的推進。

           

          5.客戶端應用

          客戶端應用是通過請求的方式同工作流執行服務交互的應用,也就是說是客戶端應用調用工作流執行服務,客戶端應用同工作流執行服務交互。它提供給用戶一種手段,以處理實例運行過程中需要人工參與的任務。

           

          6.調用的應用

          調用的應用指工作流執行服務在過程實例運行過程中調用的、用以對應用數據進行處理的應用程序和Web服務

          原文出自:
          http://www.cnblogs.com/yuziyan/archive/2012/12/08/2809346.html

          posted @ 2012-12-10 23:07 小胡子 閱讀(219) | 評論 (0)編輯 收藏

          類圖畫法

          類之間的幾種關系:泛化(Generalization)、實現(Realization)、關聯(Association)(又分一般關聯、聚合(Aggregation)、組合(Composition))、依賴(Dependency)

          一、類圖畫法

          1、  類圖的概念

          A、顯示出類、接口以及它們之間的靜態結構和關系

          B、用于描述系統的結構化設計

          2、  類圖的元素

          類、接口、協作、關系,我們只簡單介紹一下這四種元素。

          同其他的圖一樣,類圖也可以包含注解和限制。

          類圖中也可以包含包和子系統,這兩者用來將元素分組。

          有時候你也可以將類的實例放到類圖中。

          3、  類

          A、 類是對一組具有相同屬性、操作、關系和語義的對象的抽象,它是面向對象系統組織結構的核心,包括名稱部分(Name)、屬性部分(Attribute)和操作部分(Operation),見下圖。

          B、 類屬性的語法為:

          [可見性] 屬性名 [:類型] [=初始值] [{屬性字符串}]

          可見性:公有(Public)“+”、私有(Private)“-”、受保護(Protected)“#”

          類操作的語法為:

          [可見性] 操作名 [(參數表)] [:返回類型] [{屬性字符串}]

          可見性:公有(Public)“+”、私有(Private)“-”、受保護(Protected)“#”、包內公有(Package)“~”

          參數表:

          定義方式:“名稱:類型”;若存在多個參數,將各個參數用逗號隔開;參數可以具有默認值;

          屬性字符串:

          在操作的定義中加入一些除了預定義元素之外的信息。

          4、  接口

          在沒有給出對象的實現和狀態的情況下對對象行為的描述。

          一個類可以實現一個或多個接口。

          使用兩層矩形框表示,與類圖的區別主要是頂端有<<interface>>顯示:

          也可以用一個空心圓表示:

          5、  協作

          協作是指一些類、接口和其他的元素一起工作提供一些合作的行為,這些行為不是簡單地將元素 加能得到的。例如:當你為一個分布式的系統中的事務處理過程建模型時,你不可能只通過一個類來明白事務是怎樣進行的,事實上這個過程的執行涉及到一系列的 類的協同工作。使用類圖來可視化這些類和他們的關系。

          6、  關系

          這篇文章的重點,詳見第二部分。

          二、類之間的幾種關系

          1、  泛化(Generalization)

          A、 是一種繼承關系,表示一般與特殊的關系,它指定了子類如何特化父類的所有特征和行為,描述了一種“is a kind of” 的關系。例如:老虎是動物的一種,即有老虎的特性也有動物的共性。

          B、 用帶空心箭頭的實線表示,箭頭指向父類,如下圖:

          2、  實現(Realization)

          A、 是一種類與接口的關系,表示類是接口所有特征和行為的實現。

          B、 用帶空心箭頭的虛線表示,箭頭指向接口,如下圖:

          3、  關聯(Association)

          A、 一般關聯

          a、  關聯關系是類與類之間的聯結,它使一個類知道另一個類的屬性和方法,指明了事物的對象之間的聯系,如:老師與學生、丈夫與妻子。關聯可以是雙向的,也可以是單向的,還有自身關聯。

          b、  用帶普通箭頭的實心線表示。雙向的關聯可以有兩個箭頭或者沒有箭頭,單向的關聯有一個箭頭,如下圖:

           

          B、 聚合(Aggregation)

          a、  它是整體與部分(整體 has a 部分)的關系,且部分可以離開整體而單獨存在,如車和輪胎是整體和部分的關系,輪胎離開車仍然可以存在。聚合關系是關聯關系的一種,是強的關聯關系,關聯和聚合在語法上無法區分,必須考察具體的邏輯關系。

          b、  用帶空心菱形的實線表示,菱形指向整體,如下圖:

          C、 組合(Composition)

          a、  它是整體與部分的關系,但部分不能離開整體而單獨存在。如公司和部門是整體和部分的關系,沒有公司就不存在部門。組合關系是關聯關系的一種,是比聚合關系還要強的關系,它要求普通的聚合關系中代表整體的對象負責代表部分的對象的生命周期。

          b、  用帶實心菱形的實線表示,菱形指向整體,如下圖:

          4、  依賴(Dependency)

          A、 元素A的變化會影響元素B,那么B和A的關系是依賴關系,B依賴A。要避免雙向依賴,一般來說,不應該存在雙向依賴。關聯、實現、泛化都是依賴關系。

          B、 用帶箭頭的虛線表示,箭頭指向被依賴元素。

          5、  總結

          各種關系的強弱順序如下:

          泛化 = 實現 > 組合 > 聚合 > 關聯 > 依賴

          下面這張UML圖,比較形象地展現了各種類圖關系:

          原文出自:
          http://www.cnblogs.com/fuhongxue2011/archive/2012/12/09/2810408.html

          posted @ 2012-12-10 21:50 小胡子 閱讀(950) | 評論 (0)編輯 收藏

               摘要: 近日來對Ext特別感興趣,也許是它那種OO的設計思想吸引了我,也可以追溯到第一次見到EXT那種漂亮的界面開始吧.求神拜佛不如自食其力,為了一點小的問題找遍了GOOGLE也沒個結果,自己甚少去BBS混,也不熟悉規矩,只能硬著頭皮自己干了.翻源代碼是一道必不可少的工序,說來慚愧,自己對JS的認識還停留在入門階段.這里說說自己對于Ext驗證這里淺薄的理解:首先看看如下一段代碼Code highlight...  閱讀全文

          posted @ 2012-12-08 23:19 小胡子 閱讀(721) | 評論 (0)編輯 收藏

          由于HTTP協議的無狀態特性,導致在ASP.NET編程中,每個請求都會在服務端從頭到執行一次管線過程, 對于ASP.NET頁面來說,Page對象都會重新創建,所有控件以及內容都會重新生成, 因此,如果希望上一次的頁面狀態能夠在后續頁面中保留,則必需引入狀態管理功能。

          ASP.NET為了實現狀態管理功能,提供了8種方法,可幫助我們在頁面之間或者整個用戶會話期間保留狀態數據。 這些方法分為二類:視圖狀態、控件狀態、隱藏域、Cookie 和查詢字符串會以不同方式將數據發送到客戶端上。 而應用程序狀態、會話狀態和配置文件屬性(Profile)則會將數據存儲到服務端。 雖然每種方法都有不同的優點和缺點,對于小的項目來說,可以選擇自己認為最容易使用的方法, 然而,對于有著較高要求的程序,尤其是對于性能與擴展性比較關注的程序來說, 選擇不同的方法最終導致的差別可能就非常大了。

          在這篇博客中,我將談談自己對ASP.NET狀態管理方面的一些看法。
          注意:本文的觀點可能并不合適開發小型項目,因為我關注的不是易用性。

          hidden-input

          hidden-input 這個名字我是取的,表示所有type="hidden"的input標簽元素。 在中文版的MSDN中,也稱之為 隱藏域 。 hidden-input通常存在于HTML表單之內,它不會顯示到頁面中, 但可以隨表單一起提交,因此,經常用于維護當前頁面的相關狀態,在服務端我們可以使用Request.Form[]來訪問這些數據。

          一般說來,我通常使用hidden-input來保存一些中間結果,用于在多次提交中維持一系列狀態, 或者用它來保存一些固定參數用來提交給其它頁面(或網站)。 在這些場景中,我不希望用戶看到這些數據,因此,使用hidden-input是比較方便的。

          關于表單的更多介紹可參考我的博客:細說 Form (表單)

          在ASP.NET WebForm框架中,我們可以使用HiddenField控件來創建一個hidden-input控件,并可以在服務端操作它, 還可以直接以手寫的方式使用隱藏域,例如:

          <input type="hidden" name="hidden-1" value="aaaaaaa" /> <input type="hidden" name="hidden-2" value="bbbbbbb" /> <input type="hidden" name="hidden-3" value="ccccccc" /> 

          另外,我們還可以調用ClientScript.RegisterHiddenField()方法來創建隱藏域:

          ClientScript.RegisterHiddenField("hidden-4", "ddddddddd"); 

          輸出結果:

          <input type="hidden" name="hidden-4" id="hidden-4" value="ddddddddd" /> 

          這三種方法對于生成的HTML代碼來說,主要差別在于它們出現位置不同:
          1. HiddenField控件:由HiddenField的出現位置來決定(在form內部)。
          2. RegisterHiddenField方法:在form標簽的開頭位置。
          3. hidden-input:你寫在哪里就是哪里。

          優點:
          1. 不需要任何服務器資源:隱藏域隨頁面一起發送到客戶端。
          2. 廣泛的支持:幾乎所有瀏覽器和客戶端設備都支持具有隱藏域的表單。
          3. 實現簡單:隱藏域是標準的 HTML 控件,不需要復雜的編程邏輯。

          缺點:
          1. 不能在多頁面跳轉之間維持狀態。
          2. 用戶可見,保存敏感數據時需要加密。

          QueryString

          查詢字符串是存在于 URL 結尾的一段數據。下面是一個典型的查詢字符串示例(紅色部分文字):

          http://www.abc.com/demo.aspx?k1=aaa&k2=bbb&k3=ccc 

          查詢字符串經常用于頁面的數據過濾,例如:
          1. 給列表頁面增加分頁參數,list.aspx?page=2
          2. 給列表頁面增加過慮范圍,Product.aspx?categoryId=5
          3. 顯示特定記錄,ProductInfo.aspx?page=3

          關于查詢字符串的用法,我補充二點:
          1. 可以調用HttpUtility.ParseQueryString()來解析查詢字符串。
          2. 允許參數名重復:list.aspx?page=2&page=3,因此在修改URL參數時,使用替換方式而不是追加。
            關于參數重名的讀取問題,請參考我的博客:細說 Request[]與Request.Params[]

          優點:
          1. 不需要任何服務器資源:查詢字符串的數據包含在每個URL中。
          2. 廣泛的支持:幾乎所有的瀏覽器和客戶端設備均支持使用查詢字符串傳遞參數值。
          3. 實現簡單:在服務端直接訪問Request.QueryString[]可讀取數據。
          4. 頁面傳值簡單:<a href="url">或者 Response.Redirect(url) 都可以實現。

          缺點:
          1. 有長度限制。
          2. 用戶可見,不能保存敏感數據。

          Cookie

          由于HTTP協議是無狀態的,對于一個瀏覽器發出的多次請求,WEB服務器無法區分它們是不是來源于同一個瀏覽器。所以,需要額外的數據用于維護會話。 Cookie 正是這樣的一段隨HTTP請求一起被傳遞的額外數據。 Cookie 是一小段文本信息,它的工作方式就是伴隨著用戶請求和頁面在 Web 服務器和瀏覽器之間傳遞。Cookie 包含每次用戶訪問站點時 Web 應用程序都可以讀取的信息。

          與hidden-input, QueryString相比,Cookie有更多的屬性,許多瀏覽器可以直接查看這些信息:

          由于Cookie擁有這些屬性,因此在客戶端狀態管理中可以實現更多的功能,尤其是在實現客戶端會話方面具有不可替代的作用。

          關于Cookie的更多講解,請參考我的另一篇博客:細說Cookie

          優點:
          1. 可配置到期規則:Cookie可以在客戶端長期存在,也可以在瀏覽器關閉時清除。
          2. 不需要任何服務器資源:Cookie 存儲在客戶端。
          3. 簡單性:Cookie 是一種基于文本的輕量結構,包含簡單的鍵值對。
          4. 數據持久性:與其它的客戶端狀態數據相比,Cookie可以實現長久保存。
          5. 良好的擴展性:Cookie的讀寫要經過ASP.NET管線,擁有無限的擴展性。

          這里我要解釋一下Cookie 【良好的擴展性】是個什么概念,比如:
          1. 我可以實現把Cookie保存到數據庫中而不需要修改現有的項目代碼。
          2. 把SessionId這樣由ASP.NET產生的臨時Cookie讓它變成持久保存。

          缺點:
          1. 大小受到限制。
          2. 增加請求頭長度。
          3. 用戶可見,保存敏感數據時需要加密。

          ApplicationState

          應用程序狀態是指采用HttpApplicationState實現的狀態維持方式,使用代碼如下:

          Application.Lock(); Application["PageRequestCount"] = ((int)Application["PageRequestCount"]) + 1; Application.UnLock(); 

          對于這種方法,我不建議使用,因為:
          1. 與使用靜態變量差不多,直接使用靜態變量可以不需要字典查找。
          2. 選擇強類型的集合或者變量可以避免裝箱拆箱。

          ViewState,ControlState

          視圖狀態,控件狀態,二者是類似,在頁面中表現為一個hidden-input元素:

          <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="......................" /> 

          控件狀態是ASP.NET 2.0中引入,與視圖狀態相比,它不允許關閉。
          由于它們使用方式一致,而且視圖狀態是基于控件狀態的實現邏輯,所以我就不區分它們了。

          在ASP.NET的早期,微軟為了能幫助廣大開發人員提高開發效率,引用入一大批的服務端控件,并為了能將事件編程機制引入ASP.NET中,又發明了ViewState。

          這種方式雖然可以簡化開發工作量,然而卻有一些限制和缺點:
          1. 視圖狀態的數據只能用于回發(postback)。
          2. 視圖狀態的【濫用】容易導致生成的HTML較大,這會引起一個惡性循環:
            a. 過大的ViewState在序列化過程中會消耗較多的服務器CPU資源,
            b. 過大的ViewState最終生成的HTML輸出也會很大,它會浪費服務端網絡資源,
            c. 過大的ViewState輸出導致表單在下次提交時,會占用客戶端網絡資源。
            d. 過大的ViewState數據上傳到服務端后,反序列化又會消耗較多的服務器CPU資源。
            因此,整個交互過程中,用戶一直在等待,用戶體驗極差。

          在ASP.NET興起的年代,ViewState絕對是個了不起的發明。
          然而,現在很多關于ASP.NET性能優化的方法中,都會將【關閉ViewState】放在頭條位置。
          為什么會這樣呢,大家可以自己思考一下了。

          有些人認為:我現在做的程序只是在局域網內使用,使用ViewState完全沒有問題!
          然而,那些人或許沒有想過:
          1. 未來用戶可能會把它部署在互聯網上運行(對于產品來說就是遇到大客戶了)。
          2. 項目早期的設計與規劃,對后期的開發與維護來說,影響是巨大的,因為許多基礎部分通常是在早期開發的。
          當這二種情況的任何一種發生時,想再禁用ViewState,可能已經晚了。

          對于視圖狀態,我認為它解決的問題比它引入的問題要多要復雜,
          因此,我不想花時間整理它的優缺點,我只想說一句:把它關了,在web.config中關了。

          另外,我不排斥使用服務器控件,我認為:你可以使用服務端控件顯示數據,但不要用它處理回發。

          如果你仍然認為視圖狀態是不可缺少的,那我還是建議你看看ASP.NET MVC框架,看看沒有視圖狀態是不是照樣可以寫ASP.NET程序。

          Session

          Session是ASP.NET實現的一種服務端會話技術,它允許我們方便地在服務端保存與用戶有關的會話數據。

          我認為Session只有一個優點:最簡單的服務端會話實現方式。

          缺點:
          1. 當mode="InProc"時,容易丟失數據,為什么?因為網站會因為各種原因重啟。
          2. 當mode="InProc"時,Session保存的東西越多,就越占用服務器內存,對于用戶在線人數較多的網站,服務器的內存壓力會比較大。
          3. 當mode="InProc"時,程序的擴展性會受到影響,原因很簡單:服務器的內存不能在多臺服務器間共享。
          4. 當采用進程外模式時,在每次請求中,不管你用不用會話數據,所有的會話數據都為你準備好了(反序列化),這其實很是浪費資源的。
          5. 如果你沒有關閉Session,SessionStateModule就一直在工作中,尤其是全采用默認設置時,會對每個請求執行一系列的調用,浪費資源。
          6. 阻塞同一客戶端發起的多次請求(默認方式)。
          7. 無Cookie會話可能會丟失數據(重新生成已過期的會話標識符)。

          Session的這些缺點也提醒我們:
          1. 當網站的在線人數較多時,一定不要用Session保存較大的對象。
          2. 在密集型的AJAX型網站或者大量使用iframe的網站中,要關注Session可能引起的服務端阻塞問題。
          3. 當采用進程外模式時,不需要訪問Session的頁面,一定要關閉,否則會浪費服務器資源。

          如果想了解更多的Session特點,以及我對Session的看法,可以瀏覽我的博客:Session,有沒有必要使用它?

          Session的本質有二點:
          1. SessionId + 服務端字典:服務端字典保存了某個用戶的所有會話數據。
          2. 用SessionId識別不同的客戶端:SessionId通常以Cookie形式發送到客戶端。

          我認為了解Sesssion本質非常有用,因為可以借鑒并實現自己的服務端會話方法。

          關于Session我還想說一點:
          有些新手喜歡用Session來實現身份認證功能,這是一種【不正確】的方法。
          如果你的ASP.NET應用程序需要身份認證功能,請使用 Forms身份認證 或者 Windows身份認證

          Profile

          Profile 在中文版的MSDN中被稱為 配置文件屬性,這個功能是在 ASP.NET 2.0 中引入的。

          ASP.NET提供這個功能主要是為了簡化與用戶相關的個性化信息的讀寫方式。
          簡化主要體現在3個方面:
          1. 自動與某個用戶關聯,已登錄用戶或者未登錄都支持。
          2. 不需要我們設計用戶的個性化信息的保存表結構,只要修改配置文件就夠了。
          3. 不需要我們實現數據的加載與保存邏輯,ASP.NET框架替我們實現好了。

          為了使用Profile,我們首先在web.config中定義所需要的用戶個性化信息:

          <profile>     <properties>         <add name="Address"/>         <add name="Tel"/>     </properties> </profile> 

          然后,就可以在頁面中使用了:

          為什么會這樣呢?
          原因是ASP.NET已經根據web.config為我們創建了一個新類型:

          using System; using System.Web.Profile;  public class ProfileCommon : ProfileBase {     public ProfileCommon();      public virtual string Address { get; set; }     public virtual string Tel { get; set; }      public virtual ProfileCommon GetProfile(string username); } 

          有了這個類型后,當我們訪問HttpContext.Profile屬性時,ASP.NET會創建一個ProfileCommon的實例。 也正是由于Profile的強類型機制,在使用Profile時才會有智能提示功能。

          如果我們希望為未登錄的匿名用戶也提供這種支持,需要將配置修改成:

          <profile>     <properties>         <add name="Address" allowAnonymous="true" />         <add name="Tel" allowAnonymous="true"/>     </properties> </profile> <anonymousIdentification enabled="true" /> 

          Profile中的每個屬性還允許指定類型和默認值,以及序列化方式,因此,擴展性還是比較好的。

          盡管Profile看上去很美,然而,使用Profile的人卻很少。
          比如我就不用它,我也沒見有人有過它。
          為什么會這樣?

          我個人認為:它與MemberShip一樣,是個雞肋。
          通常說來,我們會為用戶信息創建一張User表,增加用戶信息時,會通過增加字段的方式解決。
          我認為這樣集中的數據才會更好,而不是說,有一部分數據由我維護,另一部分數據由ASP.NET維護。

          另一個特例是:我們根本不創建User表,直接使用MemberShip,那么Profile用來保存MemberShip沒有信息是有必要的。

          還是給Profile做個總結吧:
          優點:使用簡單。
          缺點:不實用。

          各種狀態管理的對比與總結

          前面分別介紹了ASP.NET的8種狀態管理技術,這里打算給它們做個總結。


          客戶端 服務端
          數據安全性
          數據長度限制 受硬件限制
          占用服務器資源
          集群擴展性

          表格中主要考察了數據保存與服務端水平擴展的相關重要指標。

          下面我來解釋表格的結果。
          1. 客戶端方式的狀態數據(hidden-input, QueryString, Cookie):
            a. 數據對用戶來說,可見可修改,因此數據不安全。
            b. QueryString, Cookie 都有長度限制。
            c. 數據在客戶端,因此不占用服務端資源。這個特性對于在線人數很多的網站非常重要。
            d. 數據在客戶端,因此和服務端沒有耦合關系,WEB服務器可以更容易實現水平擴展。

          2. 服務端方式的狀態數據(ApplicationState,ViewState,ControlState,Session,Profile):
            a. 數據對用戶不可見,因此安全性好。(ApplicationState,Session,Profile)
            b. 數所長度只受硬件限制,因此,對于在線人數較多的網站,需謹慎選擇。
            c. 對于存放在內存中的狀態數據,由于不能共享內存,因此會限制水平擴展能力。
            d. 如果狀態數據保存到一臺機器,會有單點失敗的可能,也會限制了水平擴展能力。

          從這個表格我們還可以得到以下結論:
          1. 如果很關注數據的安全性,應該首選服務端的狀態管理方法。
          2. 如果你關注服務端的水平擴展性,應該首選客戶端的狀態管理方法。

          會話狀態的選擇

          接下來,我們再來看看會話狀態,它與狀態管理有著一些關系,屬于比較類似的概念。

          談到會話狀態,首先我要申明一點:會話狀態與狀態不是一回事。

          本文前面所說的狀態分為二種:
          1. 頁面之間的狀態。
          2. 應用程序范圍內的狀態。

          而會話狀態是針對某個用戶來說,他(她)在多次操作之間的狀態。
          在用戶的操作期間,有可能狀態需要在頁面之間持續使用,
          也有可能服務端程序做過重啟,但數據仍然有效。
          因此,這種狀態數據更持久。

          在ASP.NET中,使用會話狀態有二個選擇:Session 或者 Cookie 。
          前者由ASP.NET實現,并有可能依賴后者。
          后者則由瀏覽器實現,ASP.NET提供讀寫方法。

          那么到底選擇哪個呢?
          如果你要問我這個問題,我肯定會說:我選 Cookie !

          下面是我選擇Cookie實現會話狀態的理由:
          1. 不會有服務端阻塞問題。
          2. 不占用服務端資源。
          3. 水平擴展沒有限制。
          4. 也支持過期設置,而且更靈活。
          5. 可以在客戶端直接使用會話數據。
          6. 可以實現更靈活的會話數據加載策略。
          7. 擴展性較好(源于ASP.NET管線的擴展性)

          如果選擇使用Cookie實現會話狀態,有3點需要特別注意:
          1. 不建議保存敏感數據,除非已加密。
          2. 只適合保存短小簡單的數據。
          3. 如果會話數據較大,可以在客戶端保存用戶標識,由服務端實現數據的加載保存邏輯。

          或許有些人認為:每種技術都有它們的優缺點,有各自的適用領域。
          我表示贊同這句話。
          但是,我們要清楚一點:每個項目的規模不一樣,性能以及擴展性要求也不同。
          對于一個小的項目來說,選擇什么方法都不是問題,
          但是,對于規模較大的項目,我們一定需要取舍。
          取舍的目標是:包裝越少越好,因為人家做了過多的包裝,就會有較多的限制,
          所以,不要只關注現在的調用是否方便,其實只要你愿意包裝,你也可以讓復雜的調用簡單化。

          改變開發方式,發現新方法

          回想一下:為什么在ASP.NET中需要狀態管理?
          答:因為與HTTP協議有關,服務端沒有保存每個請求的上次頁面狀態。

          為什么Windows計算器(這類)程序不用考慮會話問題呢?
          答:因為這類程序的界面不需要重新生成,任何變量都可表示狀態。

          再來看這樣一個場景:

          圖片左邊是一個列表頁面,允許調整每條記錄的優先級,但是有2個要求:
          1. 在移動每條記錄時,必須輸入一個調整理由。
          2. 只要輸入理由后,那條記錄可以任意調整多次。

          顯然,完成這個任務必須要有狀態才能實現。

          面對這個問題,你可以思考一下:選擇哪種ASP.NET支持的狀態管理方法都很麻煩。

          怎么辦?

          我的解決方法:創建一個JavaScript數組,用每個數組元素保存每條記錄的狀態,
          所有用戶交互操作用AJAX方式實現,這樣頁面不會刷新,JavaScript變量中的狀態一直有效。
          因此,很容易就能解決這個問題。

          這個案例也提醒我們:當發現ASP.NET提供的狀態管理功能全部不合適時, 我們需要改變開發方式了。

          為什么WEB編程都有【無狀態】問題,而桌面程序沒有?
          我認為與HTTP協議有關,但沒有絕對的關系。
          只要你能保證頁面不刷新,也能像桌面程序那樣,用JavaScript變量就能維護頁面狀態。

          原文出自:
          http://www.cnblogs.com/fish-li/archive/2012/11/21/2780086.html

          posted @ 2012-12-08 17:44 小胡子 閱讀(254) | 評論 (0)編輯 收藏

          1.本地庫導出

          mysqldump 
          -u 用戶名 -p 數據庫名 > 存放位置
          例: mysqldump 
          -uroot -p1234 testdb > /root/db/testdb.sql


          2.從遠程庫導出

          mysqldump 
          -h 主機IP -u 用戶名 -p 數據庫名 > 存放位置
          例: mysqldump 
          -h192.168.30.30 -uroot -p1234 testdb > /root/db/testdb.sql


          3.導出表結構及數據

          mysqldump 
          -u 用戶名 -p 數據庫名 表名 > 導出的文件名
          例: mysqldump 
          -uroot -p1234 testdb tab > /root/db/testdb.tab.sql


          4.導入數據庫

          mysql 
          -u用戶名 -p密碼 數據庫名 < 數據庫名
          例: mysql 
          -uroot -p1234 testdb < /root/db/back.sql
          注意:testdb 要事先創建好.


          原文出自:
          http://www.cnblogs.com/natgeo/archive/2012/12/08/2809027.html
















          posted @ 2012-12-08 17:07 小胡子 閱讀(197) | 評論 (0)編輯 收藏

          在formPanel里加個Key事件

           1  keys : [{
           2       key : Ext.EventObject.ENTER,
           3       fn : function(keyCode, e) {
           4        var field = Ext.getCmp(e.target.id);
           5        if (Ext.isDefined(field) && field != null) {
           6         if (Ext.isDefined(field.xtype)) {
           7          if (field.isXType('datefield')) {
           8           field.setValue(field.getValue());
           9          }
          10         }
          11        }
          12        if (Ext.isIE) {
          13         e.browserEvent.keyCode = Ext.EventObject.TAB;
          14        } else {
          15         var currentfield = Ext.getCmp(e.target.id);
          16         var fields = refThis.HusbandView
          17           .findByType('field');
          18         var i = 0;
          19         for (; i < fields.length; i++) {
          20          if (fields[i].id == currentfield.id)
          21           break;
          22         }
          23         while (true) {
          24          i++;
          25          if (fields.length <= i)
          26           break;
          27          if (!fields[i].disabled
          28            && fields[i].xtype != 'hidden'
          29            && !fields[i].hidden)
          30           break;
          31         }
          32         if (fields.length <= i)
          33          return;
          34         if (!fields[i].disabled) {
          35          fields[i].focus();
          36          if (Ext.isDefined(fields[i].selectText))
          37           fields[i].selectText();
          38         }
          39        }
          40       }
          41      }]

          原文出自:
          http://xlong224.blog.163.com/blog/static/601214932011102810201224/

          posted @ 2012-12-06 23:16 小胡子 閱讀(405) | 評論 (0)編輯 收藏

          原先的EditGrid無法解決回車控制問題,它的回車控制是向下跑的。而我想讓它橫著走。搞了半天終于實現了。

           1 Ext.override(Ext.grid.RowSelectionModel, {
           2                 onEditorKey : function(field, e) {
           3                     // alert('go');
           4                     var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
           5                     var shift = e.shiftKey;
           6                     Ext.log('k:' + k);
           7                     if (k == e.ENTER) {
           8                         e.stopEvent();
           9                         ed.completeEdit();
          10                         if (shift) {
          11                             newCell = g.walkCells(ed.row, ed.col - 1-1,
          12                                     this.acceptsNav, this);
          13                         } else {
          14                             // alert('go');
          15                             newCell = g.walkCells(ed.row, ed.col + 11,
          16                                     this.acceptsNav, this);
          17                         }
          18                     } else if (k == e.TAB) {
          19                         e.stopEvent();
          20                         ed.completeEdit();
          21                         if (this.moveEditorOnEnter !== false) {
          22                             if (shift) {
          23                                 newCell = g.walkCells(ed.row - 1, ed.col, -1,
          24                                         this.acceptsNav, this);
          25                             } else {
          26                                 // alert('go');
          27                                 newCell = g.walkCells(ed.row + 1, ed.col, 1,
          28                                         this.acceptsNav, this);
          29                             }
          30                         }
          31                     } else if (k == e.ESC) {
          32                         ed.cancelEdit();
          33                     }
          34                     if (newCell) {
          35                         g.startEditing(newCell[0], newCell[1]);
          36                     }
          37                 }
          38             });
          39     var sm2 = new Ext.grid.RowSelectionModel({
          40         moveEditorOnEnter : true,
          41         singleSelect : true,
          42         listeners : {
          43             rowselect : function(sm, row, rec) {
          44                 centerForm.getForm().loadRecord(rec);
          45             }
          46         }
          47 
          48     });

          原文出自:
          http://erichua.iteye.com/blog/234698

          2.

          默認extjs中editorgrid編輯單元格的時候按回車是將焦點向下移動,按照一般的邏輯應該是向右移動。

          其實只要將原先rowSelectionModel中onEditorKey方法override一下即可。

          代碼如下:


           1 Ext.override(Ext.grid.RowSelectionModel, {
           2 
           3  onEditorKey : function(field, e) {
           4   var k = e.getKey(), newCell, g = this.grid, last = g.lastEdit, ed = g.activeEditor, shift = e.shiftKey, ae, last, r, c;
           5 
           6   if (k == e.TAB) {
           7    e.stopEvent();
           8    ed.completeEdit();
           9    if (shift) {
          10     newCell = g.walkCells(ed.row, ed.col - 1-1this.acceptsNav,
          11       this);
          12    } else {
          13     newCell = g.walkCells(ed.row, ed.col + 11this.acceptsNav,
          14       this);
          15    }
          16   } else if (k == e.ENTER) {
          17    if (this.moveEditorOnEnter !== false) {
          18     if (shift) {
          19      newCell = g.walkCells(last.row, last.col - 1-1,
          20        this.acceptsNav, this);
          21     } else {
          22      newCell = g.walkCells(last.row, last.col + 11,
          23        this.acceptsNav, this);
          24     }
          25    }
          26   }
          27   if (newCell) {
          28    r = newCell[0];
          29    c = newCell[1];
          30 
          31    this.onEditorSelect(r, last.row);
          32 
          33    if (g.isEditor && g.editing) { // *** handle tabbing while
          34            // editorgrid is in edit mode
          35     ae = g.activeEditor;
          36     if (ae && ae.field.triggerBlur) {
          37      // *** if activeEditor is a TriggerField, explicitly call
          38      // its triggerBlur() method
          39      ae.field.triggerBlur();
          40     }
          41    }
          42    g.startEditing(r, c);
          43   }
          44  }
          45 })

           

          posted @ 2012-12-06 23:14 小胡子 閱讀(2216) | 評論 (0)編輯 收藏

          方法1: JMX

          很多人詢問如何通過 JMX 來管理 Quertz,很奇怪的是 Quartz 的文檔完全沒有提及這方面的問題,你可以在 quartz.properties 中通過以下配置來啟用 JMX 的支持:

          org.quartz.scheduler.jmx.export = true

          然后你就可以使用標準的 JMX 客戶端,例如 $JAVA_HOME/bin/jconsole 來連接到 Quartz 并進行遠程管理。

          方法2: RMI

          另外一個遠程管理 Quartz 的方法就是啟用 RMI。如果你用的是 RMI 的方式,就會自動一個 Quartz 實例來作為 RMI 服務器,然后你可啟動第二個 Quartz 實例來作為 RMI 客戶端,二者通過 TCP 端口進行通訊。

          服務器端調度實例配置方法(quartz.properties):

          org.quartz.scheduler.rmi.export = true
          org.quartz.scheduler.rmi.createRegistry 
          = true
          org.quartz.scheduler.rmi.registryHost 
          = localhost
          org.quartz.scheduler.rmi.registryPort 
          = 1099
          org.quartz.scheduler.rmi.serverPort 
          = 1100

          客戶端調度器配置(quartz.properties):

          org.quartz.scheduler.rmi.proxy = true
          org.quartz.scheduler.rmi.registryHost 
          = localhost
          org.quartz.scheduler.rmi.registryPort 
          = 1099

          關于 Quartz 的 RMI 特性的文檔描述請看 這里. Quartz 不提供客戶端 API,服務器端和客戶端都是使用 org.quartz.Scheduler,只是配置不同而已。通過不同的配置來執行不同的行為。對服務器端來說,調度器用來執行所有的作業;而客戶端只 是一個簡單的代理,不運行任何作業,在關閉客戶端的時候必須小心,因為它允許你也同時關閉服務器端。

          這些配置都在我的示例程序 MySchedule 中有著重說明,如果你運行的是 Web 應用,你可以看到 這個演示,你將看到我們提供了很多 quartz 的示例配置用來做遠程管理。

          如果使用 RMI 方法,你可以用 MySchedule Web UI 做為一個代理來管理 Quartz,你可以查看作業,可停止服務器的運行。

          根據我的經驗,使用 RMI 方法的弊端就是創建一個新的單點故障,如果你的服務器端口宕掉了,就無法恢復。

          原文出自:

          http://www.oschina.net/question/12_67413

          posted @ 2012-12-04 12:36 小胡子 閱讀(851) | 評論 (0)編輯 收藏

          1、Scheduler的配置

          <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
          <property name="triggers">
          <list>
          <ref bean="testTrigger"/>
          </list>
          </property>
          <property name="autoStartup" value="true"/>
          </bean> 
              說明:Scheduler包含一個Trigger列表,每個Trigger表示一個作業。

          2、Trigger的配置

          <bean id="testTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
          <property name="jobDetail" ref="testJobDetail"/>
          <property name="cronExpression" value="*/1 * * * * ?"/>
          <!-- 每隔1秒鐘觸發一次 -->
          </bean> 
              說明:

                   1)Cron表達式的格式:秒 分 時 日 月 周 年(可選)。

                         字段名                 允許的值                        允許的特殊字符  

                         秒                         0-59                               , - * /  

                         分                         0-59                               , - * /  

                         小時                   0-23                               , - * /  

                         日                         1-31                               , - * ? / L W C  

                         月                         1-12 or JAN-DEC          , - * /  

                         周幾                     1-7 or SUN-SAT            , - * ? / L C #  

                         年 (可選字段)     empty, 1970-2099      , - * /

                         “?”字符:表示不確定的值

                         “,”字符:指定數個值

                         “-”字符:指定一個值的范圍

                         “/”字符:指定一個值的增加幅度。n/m表示從n開始,每次增加m

                         “L”字符:用在日表示一個月中的最后一天,用在周表示該月最后一個星期X

                         “W”字符:指定離給定日期最近的工作日(周一到周五)

                         “#”字符:表示該月第幾個周X。6#3表示該月第3個周五

                   2)Cron表達式范例:

                           每隔5秒執行一次:*/5 * * * * ?

                           每隔1分鐘執行一次:0 */1 * * * ?

                           每天23點執行一次:0 0 23 * * ?

                           每天凌晨1點執行一次:0 0 1 * * ?

                           每月1號凌晨1點執行一次:0 0 1 1 * ?

                           每月最后一天23點執行一次:0 0 23 L * ?

                           每周星期天凌晨1點實行一次:0 0 1 ? * L

                           在26分、29分、33分執行一次:0 26,29,33 * * * ?

                           每天的0點、13點、18點、21點都執行一次:0 0 0,13,18,21 * * ?

          3、JobDetail的配置

          <bean id="testJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
          <property name="targetObject" ref="testJob"/>
          <property name="targetMethod" value="execute"/>
          <property name="concurrent" value="false"/>
          <!-- 是否允許任務并發執行。當值為false時,表示必須等到前一個線程處理完畢后才再啟一個新的線程 -->
          </bean> 
          4、業務類的配置

          <bean id="testJob" class="com.cjm.web.service.quartz.TestJob"/>  

          5、業務類源代碼

          public class TestJob { 
           
          public void execute(){ 
             
          try{                 
                 
          //.          
                }catch(Exception ex){
                 ex.printStackTrace();
                 }
               }
             } 
              說明:業務類不需要繼承任何父類,也不需要實現任何接口,只是一個普通的java類。

          注意:

               在Spring配置和Quartz集成內容時,有兩點需要注意

                     1、在<Beans>中不能夠設置default-lazy-init="true",否則定時任務不觸發,如果不明確指明default-lazy-init的值,默認是false。

                     2、在<Beans>中不能夠設置default-autowire="byName"的屬性,否則后臺會報 org.springframework.beans.factory.BeanCreationException錯誤,這樣就不能通過Bean名稱自 動注入,必須通過明確引用注入


          原文出自:

          http://www.oschina.net/question/8676_9032

          posted @ 2012-12-04 12:25 小胡子 閱讀(370) | 評論 (0)編輯 收藏

          緩存在 Solr 中充當了一個非常重要的角色,Solr 中主要有這三種緩存:
          • Filter cache(過濾器緩存),用于保存過濾器(fq 參數)和層面搜索的結果
          • Document cache(文檔緩存),用于保存 lucene 文檔存儲的字段
          • Query result(查詢緩存),用于保存查詢的結果
          還有第四種緩存,lucene 內部的緩存,不過該緩存外部無法控制到。

          通過這 3 種緩存,可以對 solr 的搜索實例進行調優。調整這些緩存,需要根據索引庫中文檔的數量,每次查詢結果的條數等。
          在調整參數前,需要事先得到 solr 示例中的以下信息:
          • 索引中文檔的數量
          • 每秒鐘搜索的次數
          • 過濾器的數量
          • 一次查詢返回最大的文檔數量
          • 不同查詢和不同排序的個數
          這些數量可以在 solr admin 頁面的日志模塊找到。假設以上的值分別為:

          • 索引中文檔的數量:1000000
          • 每秒鐘搜索的次數:100
          • 過濾器的數量:200
          • 一次查詢返回最大的文檔數量:100
          • 不同查詢和不同排序的個數:500
          然后可以開始修改 solrconfig.xml 中緩存的配置了,第一個是過濾器緩存:

          <filterCache class="solr.FastLRUCache" size="200" initialSize="200"  autowarmCount="100"/>
          第二個是查詢結果緩存:

          <queryResultCache class="solr.FastLRUCache" size="500" initialSize="500" autowarmCount="250"/>
          第三個是文檔緩存:

          <documentCache class="solr.FastLRUCache" size="11000" initialSize="11000" />
          這幾個配置是基于以上的幾個假設的值進行調優的。
          原文出自:
          http://insolr.com/forum.php?mod=viewthread&tid=7&reltid=880&pre_thread_id=19&pre_pos=5&ext=

          posted @ 2012-12-03 16:54 小胡子 閱讀(1557) | 評論 (0)編輯 收藏

          僅列出標題
          共15頁: First 上一頁 3 4 5 6 7 8 9 10 11 下一頁 Last 
          主站蜘蛛池模板: 绥中县| 孙吴县| 武冈市| 南靖县| 聊城市| 安达市| 随州市| 通河县| 禹州市| 海原县| 交城县| 德兴市| 宁化县| 龙岩市| 福鼎市| 昌黎县| 浙江省| 景谷| 宜兰县| 岑巩县| 石棉县| 上犹县| 高邑县| 新津县| 栾城县| 鹤峰县| 宝山区| 宁明县| 绍兴县| 德钦县| 绍兴市| 兴山县| 曲麻莱县| 吴川市| 天气| 新郑市| 乌鲁木齐市| 雅江县| 嘉峪关市| 江都市| 勃利县|