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

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

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

    nighty

    折騰的年華
    posts - 37, comments - 143, trackbacks - 0, articles - 0

        ActionSet是Eclipse RCP里面一非常重要的概念,因為菜單、工具欄、上下文菜單、狀態欄很多操作都是共享的,所以Action就是用來處理重復出現的東西。至于Eclipse里面定義ActionSet有非常多的技巧,可能無法一一列舉,而且使用方法也多種多樣。下面介紹的是RssOwl2項目的ui源代碼部分的一小塊。
       1.  菜單的插入點 -- GroupMarker和Separator的使用
            ApplicationActionBarAdvisor類是定義全局所有Action插入點和入口,查看fillMenuBar(IMenuManager)方法,為了簡化,以其中的輔助方法createFileMenu(IMenuManager)為例,講述一下實現菜單“文件”的內容,先看一下菜單的結構

           像Close,Import...之類的非常簡單,看一下它是如何實現New這個子菜單的。首先看一下它的源代碼如何定義插入點
         
    /* Menu: File */
      
    private void createFileMenu(IMenuManager menuBar) {
        MenuManager fileMenu 
    = new MenuManager("&File", IWorkbenchActionConstants.M_FILE);
        menuBar.add(fileMenu);

        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.FILE_START));
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.NEW_EXT));
        fileMenu.add(
    new Separator());

        fileMenu.add(getAction(ActionFactory.CLOSE.getId()));
        fileMenu.add(getAction(ActionFactory.CLOSE_ALL.getId()));
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.CLOSE_EXT));
        fileMenu.add(
    new Separator());
        fileMenu.add(getAction(ActionFactory.SAVE_AS.getId()));
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.SAVE_EXT));
        fileMenu.add(
    new Separator());
        fileMenu.add(getAction(ActionFactory.PRINT.getId()));

        fileMenu.add(
    new Separator());
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

        fileMenu.add(fReopenEditors); 
    // TODO Consider moving into a "Go" Menu!

        fileMenu.add(
    new Separator());
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.FILE_END));
        fileMenu.add(
    new Separator());

        fileMenu.add(getAction(ActionFactory.QUIT.getId()));
      }
           其中有一行fileMenu.add(new GroupMarker(IWorkbenchActionConstants.NEW_EXT)); 這里是定義一個GroupMarker作為組標記,把子菜單New容納進來。這個NEW_EXT的值是:new.ext
          現在跳回到plugin.xml去看一下它的ActionSet定義,結構如下:
    ,點擊New(menu),它的path值為:file/new.ext,這個路徑就是在createFileMenu方法定義的路徑,第一個是“File”本身的ID。也就是把子菜單New(menu)插入到指定的那個GroupMarker,ID為new.ext。然后定義了三個ID分別為bookmark,newsbin,searchmark,的groupmarker和一個folder的separator,這個三ID分別就對應上面actionSet定義的三個action,以其中的Bookmark(action)為例,它的menubarPath為:file/new_sub/bookmark,代表插入到"File"主菜單中定義的new_sub子菜單中,new_sub是New(menu)的ID。因為folder是定義為separator,所以它會有一條分隔線。這只是RssOwl的定義方法,其實以前自己做開發的時候是沒有這樣定義的,而且把子菜單New也寫在方法fillMenuBar中的,菜單把ID都寫在里面,ActionSet的配置就沒有子菜單出現了,但是這樣定義看起來就比較亂。采用這種寫法感覺比較簡潔。
        2.  Action的實現
           仍以bookmark為例,它的實現類是NewBookMarkAction,實現了IWorkbenchWindowActionDelegate, IObjectActionDelegate二個接口,第一個是ActionSet指定實現接口,第二個是對象操作菜單要求實現的接口(但事實發現沒有再定義它的配置,可能是internal版本的原因),也就是說這個Action是多功能,它將會出現在主菜單,工具欄,和局部的右鍵菜單上。主菜單和工具欄的位置都在ActionSet配置定義了,看看它的右鍵菜單實現是在哪里的,這個右鍵是在視圖Bookmarks定義的,那么跳轉到org.rssowl.ui.internal.views.explorer.BookMarkExplorer類去看看。里面有一個hookContextualMenu()方法,就是定義它的右鍵菜單的,看一下代碼實現:
    private void hookContextualMenu() {
        MenuManager manager 
    = new MenuManager();

        
    /* New Menu */
        MenuManager newMenu 
    = new MenuManager("New");
        manager.add(newMenu);

        
    /* New BookMark */
        newMenu.add(
    new Action("Bookmark"{
          @Override
          
    public void run() {
            IStructuredSelection selection 
    = (IStructuredSelection) fViewer.getSelection();
            IFolder parent 
    = getParent(selection);
            IMark position 
    = (IMark) ((selection.getFirstElement() instanceof IMark) ? selection.getFirstElement() : null);
            
    new NewBookMarkAction(fViewSite.getShell(), parent, position).run(null);
          }


          @Override
          
    public ImageDescriptor getImageDescriptor() {
            
    return OwlUI.BOOKMARK;
          }

        }
    );

       
    //其它定義
    }
         原來實現也很簡單,只是往MenuManager里面添加一個Action而已,而且run方法就是直接調用定義好的NewBookMarkAction的run方法,但是把選中對象做為參數傳進去,因為這個new是涉及當前上下文選擇對象的。
        3. 下拉類型的工具按鈕定義
        非常常見的Dropdown類型的工具欄按鈕可以把功能類型的按鈕歸為一類,做成一個下拉菜單形式,有默認的按下功能,也有可以選擇其它類似功能的下三角形式,樣子如下:

        這個dropdown的Action是定義在ActionSet配置里的。style是pulldown類型的,所以實現類NewTypeDropdownAction實現了IWorkbenchWindowPulldownDelegate接口,它的run方法就是定義默認點擊不做選擇時的事情,這個下拉菜單是實現getMenu(Control parent)方法而來,它定義了如何生成這個菜單,這就用到了最原始的SWT中的MenuItem了,并且為它們添加SelectionListener,方法實現,不用說都知道了,又是New一個先前定義好的NewBookMarkAction類,然后又是調用它的run方法。所以總結一下,Action的重用不一定是這個類的重用,關鍵是它的run方法的重用,在不同的場景下它的外在表現形式可能會多種多樣,但是它的run內容是一致的。像添加這種添加的run大部分時候都是彈出一個對話框,而對話框大都又是Winzard類型的,因為Winzard可以共享放到dialog里面。所以這種復用的思想在Eclipse里面隨處可見。
       歸結一下,其實這些技巧都是次要的,因為做GUI一個比較痛苦的事情就是經常要寫很多重復類似的代碼,抽取的不好,可能就變得不倫不類了。怎么利用它的這種思想,把復用的代碼都抽取在一起,而閱讀起來又比較輕松才是關鍵。
       知道的就這些,先介紹到這里,下次再談談其它新的發現。

    posted @ 2008-08-21 11:29 寒武紀 閱讀(1799) | 評論 (0)編輯 收藏

         摘要:     許久沒有弄RCP了,剛好近來閑暇一點,找來個RSSOwl的源代碼看看,有點收獲。RssOwl非常出名,只是可能很多人不知道它是用Java做的。以前看過RssOwl第一版的源碼,沒有詳細研究,down下來之后放上公司的共享CVS服務器,倒是幾個同事饒有興趣地研究起來。第一個版本寫得較早,可能Eclipse的RCP框架都還沒有出來,所以全部采用的SWT/JFace...  閱讀全文

    posted @ 2008-07-31 15:13 寒武紀 閱讀(2087) | 評論 (5)編輯 收藏

        最近一個程序出了點問題,對于中文參數的GET請求,服務器無法解析出正確的參數。剛好服務器的那端是另一個項目組負責,是異構系統,當初測試的時候也是走流程化,涉及到很多工作上的協調就比較麻煩,測試也不充分,像趕鴨子上架一樣就上線了,催說是項目緊急。當然這是話外,不多廢話。
        httpClient的GetMethod類加入參數的方法是如下:
    void setQueryString(NameValuePair[] params)
              Sets the query string of this HTTP method.
     void setQueryString(String queryString)
       跟蹤一下httpClient的GetMethod的源代碼,繼承自HttpMethodBase,源碼如下:
      
    public void setQueryString(String queryString) {
       
    this.queryString = queryString;
    }

        
    public void setQueryString(NameValuePair[] params) {
       LOG.trace(
    "enter HttpMethodBase.setQueryString(NameValuePair[])");
       queryString 
    = EncodingUtil.formUrlEncode(params, "UTF-8");
    }
       EncodingUtil是httpClient定義的一個編碼工具類,由于默認設置的是UTF-8,所以對于一些系統可能就無法識別。可以在外部這樣更改:
    method.setQueryString(EncodingUtil.formUrlEncode(pair, "GB2312"));另外,注意請求頭也要修改為對應的一致編碼方式,method.addRequestHeader("Content-type" , "text/html; charset=GB2312");如果這二個編碼不一致,就會引起亂碼。
       剛開始的時候嘗試過都使用一致的UTF-8,但是發現還是亂碼,這應該是服務器的原因。IE默認的就是采用操作系統Windows的中文編碼去進行Encoder的,服務器原先基本上都為IE服務的,所以改為GB2312就能正常識別得到。
       另外,上面提到的EncodingUtil這個工具是從apache的另一個組件codec包裝而來的,而非SUN的URLEncoder。有興趣的可以研讀一下源代碼。

    posted @ 2008-07-16 10:31 寒武紀 閱讀(5207) | 評論 (2)編輯 收藏

    Jakarta的httpclient3.1是最新版本,項目中需要用程序模擬瀏覽器的GET和POST動作。在使用過程中遇到不少問題。
    1. 帶附件的POST提交
        最開始都是使用MultipartPostMethod這個類,現在已經廢棄這個類了。API說明:Deprecated. Use MultipartRequestEntity in conjunction with PostMethod instead.   使用PostMethod可以實現的功能,就沒有必要再弄一個MultipartPostMethod了。下面是一段最簡單的示例:

    PostMethod post = new PostMethod();
            NameValuePair[] pairs 
    = new NameValuePair[2];
            pairs[
    0= new NameValuePair("para1""value1");
            pairs[
    0= new NameValuePair("para2""value2");
            post.setRequestBody(pairs);
            HttpClient client 
    = new HttpClient();
            
    try {
                client.executeMethod(post);
            }
     catch (HttpException e) {
                e.printStackTrace();
            }
     catch (IOException e) {
                e.printStackTrace();
            }
       這是針對一般的form形式的提交,而且這個form里面不帶附件的。如果帶附件,那么這種方法就不起作用,附件上傳的參數和普通參數無法一同在服務器獲取到。org.apache.commons.httpclient.methods.multipart 這個包就是為處理文件上傳這種多形式參數的情況的。最主要的類是Part(代表一種post object),它有二個比較重要的子類:FilePart和StringPart,一個是文件的參數,另一個就是普通的文本參數。它的典型使用方法如下:
    String url = "http://localhost:8080/HttpTest/Test";
             PostMethod postMethod 
    = new PostMethod(url);
             
             StringPart sp 
    = new StringPart("TEXT""testValue");
             FilePart fp 
    = new FilePart("file""test.txt"new File("./temp/test.txt"));
             
             MultipartRequestEntity mrp
    = new MultipartRequestEntity(new Part[]{sp, fp}, postMethod
                     .getParams());
             postMethod.setRequestEntity(mrp);
             
             
    //執行postMethod
             HttpClient httpClient = new HttpClient();
             
    try {
                httpClient.executeMethod(postMethod);
            }
     catch (HttpException e) {
                e.printStackTrace();
            }
     catch (IOException e) {
                e.printStackTrace();
            }
        在第二行PostMethod postMethod = new PostMethod();后面,有人說需要使用postMehtod.setRequestHeader("Content-type", "multipart/form-data"); Content-type的請求類型進行更改。但是我在使用過程沒有加上這一句,查了一下httpCleint的默認Content-type是application/octet-stream。應該是沒有影響的。對于MIME類型的請求,httpclient建議全用MulitPartRequestEntity進行包裝,就是上面的用法。

    2.  參數中文的處理問題
        httpclient的默認編碼都是ISO-8859-1,那肯定就無法支持中文參數了。引用一下這篇文章:http://thinkbase.net/w/main/Wiki?HttpClient+POST+%E7%9A%84+UTF-8+%E7%BC%96%E7%A0%81%E9%97%AE%E9%A2%98 ,按照作者的說法,就可以正常解決中文編碼的問題。其中最關鍵的是修改EncodingUtil這個類的一個方法實現。另外,FilePart和StringPart的構造方法都有一個帶編碼指定的參數,為了減少問題的出現,建議所有的都帶上統一的編碼,包括postMethod.getParams()。示例如下:
    String url = "http://localhost:8080/HttpTest/Test";
             PostMethod postMethod 
    = new PostMethod(url);
             
             StringPart sp 
    = new StringPart("TEXT""testValue""GB2312");
             FilePart fp 
    = new FilePart("file""test.txt"new File("./temp/test.txt"), null"GB2312");
             
             postMethod.getParams().setContentCharset(
    "GB2312");
             MultipartRequestEntity mrp
    = new MultipartRequestEntity(new Part[]{sp, fp}, postMethod
                     .getParams());
             postMethod.setRequestEntity(mrp);
             
             
    //執行postMethod
             HttpClient httpClient = new HttpClient();
             
    try {
                httpClient.executeMethod(postMethod);
            }
     catch (HttpException e) {
                e.printStackTrace();
            }
     catch (IOException e) {
                e.printStackTrace();
            }

    posted @ 2008-06-11 15:18 寒武紀 閱讀(6928) | 評論 (8)編輯 收藏

       1. 先下載VMWare Tools for linux,下面是一個下載鏈接 http://vmware.cn/Soft/UploadSoft9f4/VMware%20Workstation%206.02%C2%CC%C9%AB%BE%AB%BC%F2%D3%A2%CE%C4%B0%E6/vmware_tools_linux.rar
       2. 解壓出一個linux.iso文件,這個就是tools工具的安裝光盤鏡像。事先你必須正確安裝了Linux,我安裝的ubuntu8.04,在VM上點擊“編輯虛擬機設置”,CD-ROM方式改為“使用ISO鏡像”,選擇linux.iso,確定
       3. 啟動你的虛擬機操作系統,然后切換出來鼠標,選擇主菜單“虛擬機”--> “安裝VMware Tools”,ubuntu會自動搜索到該CDROM,直接打個桌面的圖標即可。可以看到二個文件:VMwareTools-xxx-i386.rpm和VMwareTools- xxx.tar.gz。rpm是RedHat的安裝包,這里我們應該使用gz文件,把這個gz文件直接復制到桌面,解壓,生成一個-tools-distrib 目錄。
       4. 打開終端,跳桌面這個-tools-distrib 目錄。輸入下面的命令:$ sudo ./-install.pl(回車后會提示輸入你的密碼,并且密碼不會顯示出來,表明你將以更高級權限執行一個動作——安裝軟件;再次回車后安裝開始)
       5. 安裝過程會有一系列的問題確認,類似windows的安裝向導提示,一路回車下去,采用默認方式就可以。
       6. 最后安裝成功會提示選擇桌面環境的默認分辨率。分辨率可以以后再調整。
       7. 安裝后鼠標的滑輪可能不好使了。我們這樣解決這個問題,還是打開終端,輸入:$ sudo gedit /etc/X11/xorg.conf   這個命令使系統以root權限打開鼠標配置文件/etc/X11/xorg.conf。把文件中的 Option “Protocol” “ps/2”改成 Option “Protocol” “IMPS/2” 。保存,然后重新啟動ubuntu。

       補充:關于VMware安裝ubuntu8.04和VMware tools以后,真實系統和虛擬系統的文件共享仍存在問題的,無法直接從外部的windows拖文件放入虛擬系統里面。掛載U盤或是分區也比較麻煩。后來想可以利用光驅,自己把要共享的文件制作成Windows下面的ISO文件,然后裝截入光驅,直接在虛擬光驅里面打開,就可以直接操作。

    posted @ 2008-06-03 17:27 寒武紀 閱讀(6869) | 評論 (3)編輯 收藏

       Eclipse3.3出來很久了,一直都使用英文版,剛好看到有網友介紹Eclipse的一個Project,叫Babel,官方的描述這樣:Eclipse is a global community. It is in everyone's interest to ensure that Eclipse is available and translated in as many locales as possible. 項目的主頁地址是:http://www.eclipse.org/babel/ 。按照說明從這里可以下載安裝到語言包。
       直接從Eclipse3.3的菜單"Help --> Software Updates --> Find and Insatll...",新建一個遠程站點,URL為 http://download.eclipse.org/technology/babel/update-site/ ,然后直接在線安裝。在彈出的語言選擇界面上選擇中文簡體。如下圖:
       

        網絡情況如果正常的話,安裝應該不會有問題的,中間可能會彈出幾次下載jar文件失敗的對話框,繼續retry就行。
       
        最后重啟一下,可以看到都變成中文界面的。
       
     
      原來是3.3的Eclipse,怎么變成3.2呢?原因估計是語言插件的版本是3.2的導致的,所以你看到有一些地方漢化并不完全,像Error Log視圖的標題,項目右鍵菜單,以及一些頂級菜單都沒有完全漢化。
      希望以后Babel項目后面更新跟得上主版本的變化,不過習慣了英文版的,其實也是差不多的。

    posted @ 2008-05-30 15:44 寒武紀 閱讀(13945) | 評論 (13)編輯 收藏

       普通的程序交互方式有命令行和GUI形式。對于GUI樣式,交互的設計可以多種多樣,但是Java做命令行交互,似乎存在著一些不足。
       命令行交互是傳統的交互方式,如果程序有時候需要在Unix或是Linux等系統上運動時,以這種方式出現的可能性就比較大。命令行包括
       輸入和回顯問題,一般是以行結束,或是以某個結束符為終命令終止標識。System.out 和System.err就用于標準的輸出和錯誤輸出,System.in用于標準的輸入接受,一般情況下都是指鍵盤。
       如果接受參數輸入,一般的程序結構如下:
      
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    System.out.println(
    "==Please input password==:");
    String pass 
    = in.readLine();
       輸入的時候顯示屏自動進行輸入回顯。這個時候如果遇到輸入密碼等敏感數據的時候,就無法用*或是#這樣的符號進行回顯屏蔽,容易暴露安全問題。
       解決的可能想法:
       1.  通過監聽鍵盤事件,對輸入的回顯進行截獲取,把回顯進行屏蔽,但是監聽器如何知道何時是輸入密碼,何時是輸入普通數據?比較難以控制,而且這種監聽應該是線程化的,可能會存在一些意想不到的問題。
       2.  如果用純Java難以實現,那么是否可以使用其它語言的功能進行補充,比如JNI,或是Windows下面的Dos腳本,Linux平臺的Shell腳本來進行補充。不過這樣就不太平臺無關了。
       3.  可能sun發現了這個不足之處,從1.6版本開始,增加了一個java.io.Console類,代表與當前 Java 虛擬機關聯的基于字符的控制臺設備,這個Console是對原來System.in這種不足的補充,提供了像readPassword()等這樣的實用方法,具體請參考API文檔,就是專門用于對敏感信息的讀取。但是這是基于Java1.6的,如果有些場景受限制,不能使用1.6,那么還是無法解決上面的問題。后來查閱了一下Console類的實現方式,想直接把它的實現方式移植到1.4.xx上是比較難的,因為用到了一些高版本的新特性。使用Console要注意的是:虛擬機是否具有控制臺取決于底層平臺,還取決于調用虛擬機的方式。如果虛擬機從一個交互式命令行開始啟動,且沒有重定向標準輸入和輸出流,那么其控制臺將存在,并且通常連接到鍵盤并從虛擬機啟動的地方顯示。如果虛擬機是自動啟動的(例如,由后臺作業調度程序啟動),那么它通常沒有控制臺。如果你在Eclipse里面啟動程序調用Console,那么通常是沒有控制臺,還是得從外部的命令行方式才能調用得到。
       總體想一下,感覺應該還是從第2點出發,犧牲掉一點通用性,這樣才能滿足這種功能需求。

    posted @ 2008-05-23 09:41 寒武紀 閱讀(4134) | 評論 (1)編輯 收藏

        剛好最近項目中需要用到一點加密的東西,java安全類庫提供了一個java.security.MessageDigest類,此 MessageDigest 類為應用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。信息摘要是安全的單向哈希函數,它接收任意大小的數據,并輸出固定長度的哈希值。有現成的當然是最好的,省事省力。
        MD5的非常有實際應用性。有網友給出這樣的描述,可以參照一下:http://blog.csdn.net/Daping_Zhang/archive/2005/05/28/382688.aspx
         該類的getInstance(String algorithm) 方法返回一個MessageDigest的實體,加密的一系統的digest()方法和update(byte input)方法。加密后返回一個byte[],16位,我們經常見到很多開源網站的下載地址會有一個[md5]的鏈接,打開其實就是一小段文本內容。例如:
        MD5 (commons-logging-1.1.1-bin.zip) = f88520ed791673aed6cc4591bc058b55
        這是Jakarta的logging組件下載時提供的MD5摘要信息,是對這個zip包進行全文加密生成的摘要,摘要碼就是后面的f88520ed791673aed6cc4591bc058b55,如果你下載以后,按照MD5的算法生成自己的摘要,如果這二個摘要一樣,就證明這個文件是沒有被人篡改過的。
        遇到的問題是Java的MessageDigest類執行后返回的byte[16]得轉換成十六進制的字符串,如果直接用new String(byte[]),得到的結果將是不正確的。算法有很多網友提供了,照搬了。比較有趣的是,commons-logging提供的那個MD5居然和我自己生成的不一樣(難道文件被修改過?),后來嘗試了其它地方提供的MD5碼,都沒有問題。
        有很多相關的現成代碼,搜集了一下整理如下(經過驗證):

    public class MD5Builder {

        
    static Logger logger = Logger.getLogger(MD5Builder.class);
         
    // 用來將字節轉換成 16 進制表示的字符
        static char hexDigits[] = '0''1''2''3''4''5''6''7''8',
                
    '9''a''b''c''d''e''f' }

        
        
    /**
         * 對文件全文生成MD5摘要
         * 
    @param file   要加密的文件
         * 
    @return MD5摘要碼
         
    */

        
    public static String getMD5(File file) {
            FileInputStream fis 
    = null;
            
    try {
                MessageDigest md 
    = MessageDigest.getInstance("MD5");

                logger.info(
    "MD5摘要長度:" + md.getDigestLength());
                fis 
    = new FileInputStream(file);
                
    byte[] buffer = new byte[2048];
                
    int length = -1;
                logger.info(
    "開始生成摘要");
                
    long s = System.currentTimeMillis();
                
    while ((length = fis.read(buffer)) != -1{
                    md.update(buffer, 
    0, length);
                }

                logger.info(
    "摘要生成成功,總用時: "
                        
    + (System.currentTimeMillis() - s) + "ms");
                
    byte[] b = md.digest();
                
    return byteToHexString(b);
                
    // 16位加密
                
    // return buf.toString().substring(8, 24);
            }
     catch (Exception ex) {
                logger.error(ex);
                ex.printStackTrace();
                
    return null;
            }
    finally {
                
    try {
                    fis.close();
                }
     catch (IOException ex) {
                    ex.printStackTrace();
                }

            }

        }


        
    /**
         * 對一段String生成MD5加密信息
         * 
    @param message 要加密的String
         * 
    @return 生成的MD5信息
         
    */

        
    public static String getMD5(String message){
            
    try {
                MessageDigest md 
    = MessageDigest.getInstance("MD5");
                logger.info(
    "MD5摘要長度:" + md.getDigestLength());
                
    byte[] b = md.digest(message.getBytes());
                
    return byteToHexString(b);
            }
     catch (NoSuchAlgorithmException e) {
                logger.error(e);
                e.printStackTrace();
                
    return null;
            }

        }

        
        
    /**
         * 把byte[]數組轉換成十六進制字符串表示形式
         * 
    @param tmp    要轉換的byte[]
         * 
    @return 十六進制字符串表示形式
         
    */

        
    private static String byteToHexString(byte[] tmp) {
            String s;
            
    // 用字節表示就是 16 個字節
            char str[] = new char[16 * 2]; // 每個字節用 16 進制表示的話,使用兩個字符,
            
    // 所以表示成 16 進制需要 32 個字符
            int k = 0// 表示轉換結果中對應的字符位置
            for (int i = 0; i < 16; i++// 從第一個字節開始,對 MD5 的每一個字節
                
    // 轉換成 16 進制字符的轉換
                byte byte0 = tmp[i]; // 取第 i 個字節
                str[k++= hexDigits[byte0 >>> 4 & 0xf]; // 取字節中高 4 位的數字轉換, 
                
    // >>> 為邏輯右移,將符號位一起右移
                str[k++= hexDigits[byte0 & 0xf]; // 取字節中低 4 位的數字轉換
            }

            s 
    = new String(str); // 換后的結果轉換為字符串
            return s;
        }

    }

      

    posted @ 2008-05-08 15:02 寒武紀 閱讀(6544) | 評論 (2)編輯 收藏

        一般而言,我們平常接觸的大多數項目都應該是單純使用B/S或是C/S,除非在特殊場合,否則比較少混合使用B/S,C/S架構。首先說一下對這二種架構特點的一些個人理解。B/S應該是目前很多項目都應用的架構,瀏覽器的方式使得用戶的使用十分方便,用戶可以何時何地通過Internet訪問URL而進行相應的工作,升級維護也能比較集中,缺點就是瀏覽器的表現能力受限以及常常受非議的安全性問題,如果軟件的應用范圍區域不集中,而且用戶經常變換地點進行訪問,那么這種架構是非常適合的。C/S架構的C端有非常強的處理能力,所以在交互表現和安全方面可以做得比瀏覽器強,但是缺點也是非常明顯的,安裝部署、升級維護、版本兼容都是比較頭大的事情,一般的適用場景是集中的辦公室場所,用戶使用范圍相對穩定,以及一些對業務處理非常復雜的場合,為了降低服務器的負荷,同樣需要C模式的支持。
        以前接觸過的電信領域,就有過混合架構的軟件。但是都是非常寵大,一直都對其實現方案比較感興趣,但是都沒有機會進一步了解。最近搜索了一下相關的資料,總結一下混合應用的一些想法(只針對Java方向)。
        ①混合架構的問題集中點。服務端共享,客戶端采用不同的表現方式,共享的應該是業務層接口,持久層應該是屏蔽的。應用層的消息傳遞就是整個應用的關鍵所在,雖然像Jakarta提供的httpClient這種模仿瀏覽器的組件,但是畢竟是模仿,在很多方面的功能還是缺失的。
        ②最傳統的方式是采用EJB做為服務,這個寵然大物容易讓人害怕,不過在分布式的系統中它還是有應用優勢的,像電信和金融這種行業應用還是比較廣的,而且現成的中間件和應用服務器商都比較多,像Oracel、BEA、IBM、Sun都有成熟的應用產品,當然開發的成本和人力投入也是恐龍級數據的。
        ③有網友說在C端直接訪問數據庫,B/S結構不變,也就是通過數據庫進行共享。這種方式是不可取的,二個缺點:把服務器的業務邏輯搬到了C端上,嚴格上講是不安全的,升級維護也非常麻煩;并發控制的壓力都在數據庫上。
        ④采用RMI,這個老古董相信應該很多人都不使用了,因為它的使用要一連串的手續,比如服務接口定義必須實現Remote接口,服務Server在實現時必須繼承UnicastRemoteobject類,必須使用rmic指令產生stub和skeleton等,設置上繁雜。
        ⑤Spring 遠程服務。這個應該說是比較可取的,大家都比較喜歡輕量級的東西。就如第一點所說的,通過遠程服務,我們可以在客戶直接調用服務端的服務接口,就像本地調用一樣,Spring對遠程服務提供了好幾種實現方案。
        ⑥WebService。適合異構環境,但是WSDL的這種方式相對來說會比較耗費資料,因為標準定義除了業務內容外,還有許多另外的說明內容。
        Spring遠程服務實現方案介紹:
        ⑴Spring + RMI。Spring把傳統的RMI方式的繁雜設置去掉,只要配置Bean文件就和定義服務接口可以。RMI的服務啟動和管理都交給Spring來處理。RMI訪問的缺點就是對防火墻的穿透力比較差。
        ⑵Spring + Caucho的Hessian、Burlap。Hessian使用Http將對象以中性的二進制消息進行傳送,而不像RMI使用Java的序列化格式(這種序列化是專制的,不是Sun提供的序列化機制),由于是二進制消息,所以不受限于某種實現語言,傳輸時所需要的帶寬較小是其優點。Burlap是以XML文件格式傳送對象,XML文件有較高可讀性,應用程序只要能解釋XML就能接收消息,當然也不限于某種語言,但是組裝XML和解釋XML都需要消耗資源,當傳輸大數據時性能應該存在問題。
        ⑶Spring + Http Invoker。由于Hessian的序列化機制不是正統的Java序列化機制,所以當遇到傳輸復雜的業務模型時,就會存在各種問題,為此,Spring又提供了Http Invoker,同樣是使用Http傳送對象,而且是使用Java的序列化機制。相比RMI,Http對防火墻的穿透力要強。
        后來嘗試了最后的這種Http Invoker方式,是在Spring2.0版本下嘗試的,開發非常簡單,網上也有大量的資料介紹。應該說從這里入口可以做一些嘗試。目前遇到的一個項目就需要混合架構,B/S采用Spring2 + Struts2 + Hiberntae3,瀏覽器只提供一些查詢功能和數據展現,C端采用Eclipse的RCP平臺,共享服務器的業務接口,調用就采用Http Invoker遠程服務,復雜的業務功能都集中在C端上。

    posted @ 2008-05-06 12:43 寒武紀 閱讀(13767) | 評論 (25)編輯 收藏

        1. 驅動器
                如果安裝了DB2客戶端,則到安裝目錄下的sqllib/java目錄下面找到二個jar包:db2jcc.jar和db2jcc_license_cu.jar,把它們添加到你的classpath中去,有的人說用db2java.zip也可以連接,但是我嘗試了,總是無法連接。如果沒有這二個jar包,到網上搜索一下,有些網友已經上傳了。驅動器名稱是:com.ibm.db2.jcc.DB2Driver。
        2. URL寫法
               連接的URL正確寫法是:jdbc:db2://[IP地址]:[端口]/[數據庫名],例如:jdbc:db2://99.1.99.114:50000/dwsdemo,要確保URL正確,你可以先在DB2的命令行測試一下是否能正確連接上。
        有個不太明白的地方就是為什么IBM提供的驅動器包命名有的地方是大寫,比如:COM.ibm.db2.app

    posted @ 2008-04-17 11:14 寒武紀 閱讀(7276) | 評論 (8)編輯 收藏

    僅列出標題
    共4頁: 上一頁 1 2 3 4 下一頁 
    主站蜘蛛池模板: 久久午夜羞羞影院免费观看| 亚洲第一区香蕉_国产a| 麻豆国产精品免费视频| 男女交性无遮挡免费视频| youjizz亚洲| 久久亚洲精品国产精品| 亚洲人成人网站在线观看| 全免费a级毛片免费看无码| 亚洲免费福利视频| 日本免费在线观看| 国产视频精品免费视频| 深夜特黄a级毛片免费播放| 亚洲人成电影网站色| 久久精品国产亚洲av麻豆蜜芽| 亚洲成人在线电影| 亚洲精品无码高潮喷水在线| 亚洲精品无码久久久久AV麻豆| 在线观看免费a∨网站| 成年在线观看网站免费| 最近新韩国日本免费观看| 久久国产精品2020免费m3u8 | 久久不见久久见中文字幕免费| 国产成人一区二区三区视频免费| 亚洲国产免费综合| 一进一出60分钟免费视频| 免费一区二区无码视频在线播放| 国产精品亚洲专区无码WEB| 亚洲一卡2卡3卡4卡5卡6卡| 亚洲综合中文字幕无线码| 亚洲AV成人无码天堂| 亚洲不卡在线观看| 色偷偷亚洲女人天堂观看欧| 亚洲AV一二三区成人影片| 在线观看日本亚洲一区| 亚洲黄页网在线观看| 亚洲日本人成中文字幕| 中文字幕在线观看亚洲视频| 亚洲日韩精品无码专区加勒比| 亚洲精品国产第一综合99久久| 亚洲色最新高清av网站| 久久精品国产亚洲av天美18|