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

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

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

    隨筆 - 154  文章 - 60  trackbacks - 0
    <2008年1月>
    303112345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    聲明:

    該blog是為了收集資料,認(rèn)識(shí)朋友,學(xué)習(xí)、提高技術(shù),所以本blog的內(nèi)容除非聲明,否則一律為轉(zhuǎn)載!!

    感謝那些公開自己技術(shù)成果的高人們!!!

    支持開源,尊重他人的勞動(dòng)!!

    常用鏈接

    留言簿(3)

    隨筆分類(148)

    隨筆檔案(143)

    收藏夾(2)

    其他

    學(xué)習(xí)(技術(shù))

    觀察思考(非技術(shù))

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    --------------------------第一個(gè):簡(jiǎn)單明了-------------------
    http://www.ieee.org.cn/dispbbs.asp?boardID=41&ID=13873
    代碼:
    import java.security.*
    import java.security.spec.*

    class MD5_Test

    public final static String MD5(String s)
    char hexDigits[] = 
    '0''1''2''3''4''5''6''7''8''9''a''b''c''d'
    'e''f'}

    try 
    byte[] strTemp = s.getBytes(); 
    MessageDigest mdTemp 
    = MessageDigest.getInstance("MD5"); 
    mdTemp.update(strTemp); 
    byte[] md = mdTemp.digest(); 
    int j = md.length; 
    char str[] = new char[j * 2]; 
    int k = 0
    for (int i = 0; i < j; i++
    byte byte0 = md[i]; 
    str[k
    ++= hexDigits[byte0 >>> 4 & 0xf]; 
    str[k
    ++= hexDigits[byte0 & 0xf]; 
    }
     
    return new String(str); 
    }
     
    catch (Exception e)
    return null
    }
     
    }
     
    public static void main(String[] args)
    //MD5_Test aa = new MD5_Test(); 

    System.out.print(MD5_Test.MD5(
    "XX")); 
    }


    -----------------第二個(gè):說(shuō)明注釋詳細(xì)---------------
    http://m.tkk7.com/haogj/archive/2006/07/04/56604.html

    MD5即Message-Digest Algorithm 5(信息-摘要算法5),是一種用于產(chǎn)生數(shù)字簽名的單項(xiàng)散列算法,在1991年由MIT Laboratory for Computer Science(IT計(jì)算機(jī)科學(xué)實(shí)驗(yàn)室)和RSA Data Security Inc(RSA數(shù)據(jù)安全公司)的Ronald L. Rivest教授開發(fā)出來(lái),經(jīng)由MD2、MD3和MD4發(fā)展而來(lái)。MD5算法的使用不需要支付任何版權(quán)費(fèi)用。它的作用是讓大容量信息在用數(shù)字簽名軟件簽私人密匙前被"壓縮"成一種保密的格式(將一個(gè)任意長(zhǎng)度的“字節(jié)串”通過一個(gè)不可逆的字符串變換算法變換成一個(gè)128bit的大整數(shù),換句話說(shuō)就是,即使你看到源程序和算法描述,也無(wú)法將一個(gè)MD5的值變換回原始的字符串,從數(shù)學(xué)原理上說(shuō),是因?yàn)樵嫉淖址袩o(wú)窮多個(gè),這有點(diǎn)象不存在反函數(shù)的數(shù)學(xué)函數(shù)。)
       
       在 Java 中,java.security.MessageDigest 中已經(jīng)定義了 MD5 的計(jì)算,所以我們只需要簡(jiǎn)單地調(diào)用即可得到 MD5 的128 位整數(shù)。然后將此 128 位計(jì) 16 個(gè)字節(jié)轉(zhuǎn)換成 16 進(jìn)制表示即可。

    代碼:
    package com.tsinghua;

    /**
     * MD5的算法在RFC1321 中定義
     * 在RFC 1321中,給出了Test suite用來(lái)檢驗(yàn)?zāi)愕膶?shí)現(xiàn)是否正確: 
     * MD5 ("") = d41d8cd98f00b204e9800998ecf8427e 
     * MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 
     * MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72 
     * MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0 
     * MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b 
     * 
     * 
    @author haogj
     *
     * 傳入?yún)?shù):一個(gè)字節(jié)數(shù)組
     * 傳出參數(shù):字節(jié)數(shù)組的 MD5 結(jié)果字符串
     
    */

    public class MD5 {
     
    public static String getMD5(byte[] source) {
      String s 
    = null;
      
    char hexDigits[] = {       // 用來(lái)將字節(jié)轉(zhuǎn)換成 16 進(jìn)制表示的字符
         '0''1''2''3''4''5''6''7''8''9''a''b''c''d',  'e''f'}

       
    try
       
    {
        java.security.MessageDigest md 
    = java.security.MessageDigest.getInstance( "MD5" );
        md.update( source );
        
    byte tmp[] = md.digest();          // MD5 的計(jì)算結(jié)果是一個(gè) 128 位的長(zhǎng)整數(shù),
                                                    
    // 用字節(jié)表示就是 16 個(gè)字節(jié)
        char str[] = new char[16 * 2];   // 每個(gè)字節(jié)用 16 進(jìn)制表示的話,使用兩個(gè)字符,
                                                     
    // 所以表示成 16 進(jìn)制需要 32 個(gè)字符
        int k = 0;                                // 表示轉(zhuǎn)換結(jié)果中對(duì)應(yīng)的字符位置
        for (int i = 0; i < 16; i++{          // 從第一個(gè)字節(jié)開始,對(duì) MD5 的每一個(gè)字節(jié)
                                                     
    // 轉(zhuǎn)換成 16 進(jìn)制字符的轉(zhuǎn)換
         byte byte0 = tmp[i];                 // 取第 i 個(gè)字節(jié)
         str[k++= hexDigits[byte0 >>> 4 & 0xf];  // 取字節(jié)中高 4 位的數(shù)字轉(zhuǎn)換, 
                                                                 
    // >>> 為邏輯右移,將符號(hào)位一起右移
         str[k++= hexDigits[byte0 & 0xf];            // 取字節(jié)中低 4 位的數(shù)字轉(zhuǎn)換
        }
     
        s 
    = new String(str);                                 // 換后的結(jié)果轉(zhuǎn)換為字符串

       }
    catch( Exception e )
       
    {
        e.printStackTrace();
       }

       
    return s;
     }

    }



    測(cè)試代碼:

    import com.tsinghua.*
    public class TestMD5
    {
     
    public static void main( String xu[] )
     
    // 計(jì)算 "a" 的 MD5 代碼,應(yīng)該為:0cc175b9c0f1b6a831c399e269772661
      System.out.println( MD5.getMD5("a".getBytes()) );
     }

    }



    -----------第三個(gè):服務(wù)周到--------
    MD5加密算法嚴(yán)密,安全性較高,廣泛應(yīng)用于系統(tǒng)身份驗(yàn)證、文件完整性驗(yàn)證中。Java API中java.security包中包含MessageDigest類,可以實(shí)現(xiàn)MD5算法的簡(jiǎn)單應(yīng)用,譬如將指定的普通明文轉(zhuǎn)換成MD5密碼,參考源代碼如下:

    /* *************************************************************
     * Project: bobToolkit <p>
     * Package: bob.sec.MD5 <p>
     * Filename: MD5Util.java<p>
     * Created by BobChen on 2007-3-29 <p>
     * ////////////////////////////////////////////////////////////
     *  Date      Author         Description
     * 2007-3-29    BobChen        init: object MD5Util
     * ***********************************************************/
    package bob.sec.MD5;

    import java.security.MessageDigest;

    public class MD5Util {
        public final static String MD5(String s) {
            char hexDigits[] = { '0', '1', '2', '3', '4',
                                 '5', '6', '7', '8', '9',
                                 'A', 'B', 'C', 'D', 'E', 'F' };
            try {
                byte[] btInput = s.getBytes();
                MessageDigest mdInst = MessageDigest.getInstance("MD5");
                mdInst.update(btInput);
                byte[] md = mdInst.digest();
                int j = md.length;
                char str[] = new char[j * 2];
                int k = 0;
                for (int i = 0; i < j; i++) {
                    byte byte0 = md[i];
                    str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                    str[k++] = hexDigits[byte0 & 0xf];
                }
                return new String(str);
            }
            catch (Exception e) {
                // e.printStackTrace();
                return null;
            }
        }

        public static void main(String[] args) {
            System.out.print(MD5Util.MD5("AusITcim#1485"));
        }

    }

    ---------- 運(yùn)行 ----------
    EF277661A4C821C9007ACB52E1D883EC
    輸出完成 (耗時(shí) 0 秒) - 正常終止
     

     

    ----------------------JSP頁(yè)面調(diào)用-------------------------------

    ----------

    String u_password=new String(request.getParameter("u_password").getBytes("ISO-8859-1"));

    u_password=(new MD5Util().MD5(u_password));


    ---------

    String u_id=new String(request.getParameter("u_id").getBytes("ISO-8859-1"));


    String u_password=new String(request.getParameter("u_password").getBytes("ISO-8859-1"));


    u_password=(new MD5Util().MD5(u_password));



    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1621920

    ----------第四個(gè):java MD5算法返回?cái)?shù)字型字串 --------

    常有人問及MD5算法為何有些程序片斷返回完全數(shù)字型結(jié)果而有些返回?cái)?shù)字與字母的混合字串。

    其實(shí)兩種返回結(jié)果只是因?yàn)榧用芙Y(jié)果的不同顯示形式,Blog中已經(jīng)有.Net的實(shí)現(xiàn),在此附加JAVA實(shí)現(xiàn),供參考。

    JAVA的標(biāo)準(zhǔn)類庫(kù)理論上功能也很強(qiáng)大,但由于虛擬機(jī)/運(yùn)行時(shí)的實(shí)現(xiàn)太多,加之版本差異,有些代碼在不同環(huán)境下運(yùn)行會(huì)出現(xiàn)奇怪的異常結(jié)果,尤其以涉及字符集的操作為甚。

    package com.bee.framework.common;

    import java.security.MessageDigest;

    public class MD5Encrypt {
      public MD5Encrypt() {
      }

      private final static String[] hexDigits = {
          "0", "1", "2", "3", "4", "5", "6", "7",
          "8", "9", "a", "b", "c", "d", "e", "f"};

      /**
       * 轉(zhuǎn)換字節(jié)數(shù)組為16進(jìn)制字串
       * @param b 字節(jié)數(shù)組
       * @return 16進(jìn)制字串
       */
      public static String byteArrayToString(byte[] b) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
          //resultSb.append(byteToHexString(b[i]));//若使用本函數(shù)轉(zhuǎn)換則可得到加密結(jié)果的16進(jìn)制表示,即數(shù)字字母混合的形式
          resultSb.append(byteToNumString(b[i]));//使用本函數(shù)則返回加密結(jié)果的10進(jìn)制數(shù)字字串,即全數(shù)字形式
        }
        return resultSb.toString();
      }

      private static String byteToNumString(byte b) {

        int _b = b;
        if (_b < 0) {
          _b = 256 + _b;
        }

        return String.valueOf(_b);
      }

      private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
          n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
      }

      public static String MD5Encode(String origin) {
        String resultString = null;

        try {
          resultString = new String(origin);
          MessageDigest md = MessageDigest.getInstance("MD5");
          resultString =
    byteArrayToString(md.digest(resultString.getBytes()));
        }
        catch (Exception ex) {

        }
        return resultString;
      }

      public static void main(String[] args) {
        MD5Encrypt md5encrypt = new MD5Encrypt();
        System.out.println(MD5Encode("10000000"));
      }
    }



    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=470562

    ----------第五個(gè):理論---------

    MD5的Java Bean實(shí)現(xiàn)


    2001 年 3 月 01 日

    編者的話:

    雖然 MD5 簽名算法在 jdk 中早已實(shí)現(xiàn)(如 MessageDigest類),但作者從 MD5 的原理分析講述 MD5 具體算法的 Java實(shí)現(xiàn)并給出一個(gè)完整的示例程序,我想這對(duì)我們的讀者來(lái)說(shuō)還是會(huì)有很多幫助的。

    MD5簡(jiǎn)介

    MD5的全稱是Message-Digest Algorithm 5,在90年代初由MIT的計(jì)算機(jī)科學(xué)實(shí)驗(yàn)室和RSA Data Security Inc發(fā)明,經(jīng)MD2、MD3和MD4發(fā)展而來(lái)。

    Message-Digest泛指字節(jié)串(Message)的Hash變換,就是把一個(gè)任意長(zhǎng)度的字節(jié)串變換成一定長(zhǎng)的大整數(shù)。請(qǐng)注意我使用了“字節(jié)串”而不是“字符串”這個(gè)詞,是因?yàn)檫@種變換只與字節(jié)的值有關(guān),與字符集或編碼方式無(wú)關(guān)。

    MD5將任意長(zhǎng)度的“字節(jié)串”變換成一個(gè)128bit的大整數(shù),并且它是一個(gè)不可逆的字符串變換算法,換句話說(shuō)就是,即使你看到源程序和算法描述,也無(wú)法將一個(gè)MD5的值變換回原始的字符串,從數(shù)學(xué)原理上說(shuō),是因?yàn)樵嫉淖址袩o(wú)窮多個(gè),這有點(diǎn)象不存在反函數(shù)的數(shù)學(xué)函數(shù)。

    MD5的典型應(yīng)用是對(duì)一段Message(字節(jié)串)產(chǎn)生fingerprint(指紋),以防止被“篡改”。舉個(gè)例子,你將一段話寫在一個(gè)叫readme.txt文件中,并對(duì)這個(gè)readme.txt產(chǎn)生一個(gè)MD5的值并記錄在案,然后你可以傳播這個(gè)文件給別人,別人如果修改了文件中的任何內(nèi)容,你對(duì)這個(gè)文件重新計(jì)算MD5時(shí)就會(huì)發(fā)現(xiàn)。如果再有一個(gè)第三方的認(rèn)證機(jī)構(gòu),用MD5還可以防止文件作者的“抵賴”,這就是所謂的數(shù)字簽名應(yīng)用。

    MD5還廣泛用于加密和解密技術(shù)上,在很多操作系統(tǒng)中,用戶的密碼是以MD5值(或類似的其它算法)的方式保存的,用戶Login的時(shí)候,系統(tǒng)是把用戶輸入的密碼計(jì)算成MD5值,然后再去和系統(tǒng)中保存的MD5值進(jìn)行比較,而系統(tǒng)并不“知道”用戶的密碼是什么。

    一些黑客破獲這種密碼的方法是一種被稱為“跑字典”的方法。有兩種方法得到字典,一種是日常搜集的用做密碼的字符串表,另一種是用排列組合方法生成的,先用MD5程序計(jì)算出這些字典項(xiàng)的MD5值,然后再用目標(biāo)的MD5值在這個(gè)字典中檢索。

    即使假設(shè)密碼的最大長(zhǎng)度為8,同時(shí)密碼只能是字母和數(shù)字,共26+26+10=62個(gè)字符,排列組合出的字典的項(xiàng)數(shù)則是P(62,1)+P(62,2)….+P(62,8),那也已經(jīng)是一個(gè)很天文的數(shù)字了,存儲(chǔ)這個(gè)字典就需要TB級(jí)的磁盤組,而且這種方法還有一個(gè)前提,就是能獲得目標(biāo)賬戶的密碼MD5值的情況下才可以。

    在很多電子商務(wù)和社區(qū)應(yīng)用中,管理用戶的Account是一種最常用的基本功能,盡管很多Application Server提供了這些基本組件,但很多應(yīng)用開發(fā)者為了管理的更大的靈活性還是喜歡采用關(guān)系數(shù)據(jù)庫(kù)來(lái)管理用戶,懶惰的做法是用戶的密碼往往使用明文或簡(jiǎn)單的變換后直接保存在數(shù)據(jù)庫(kù)中,因此這些用戶的密碼對(duì)軟件開發(fā)者或系統(tǒng)管理員來(lái)說(shuō)可以說(shuō)毫無(wú)保密可言,本文的目的是介紹MD5的Java Bean的實(shí)現(xiàn),同時(shí)給出用MD5來(lái)處理用戶的Account密碼的例子,這種方法使得管理員和程序設(shè)計(jì)者都無(wú)法看到用戶的密碼,盡管他們可以初始化它們。但重要的一點(diǎn)是對(duì)于用戶密碼設(shè)置習(xí)慣的保護(hù)。

    有興趣的讀者可以從這里取得MD5也就是RFC 1321的文本。http://www.ietf.org/rfc/rfc1321.txt





    回頁(yè)首


    實(shí)現(xiàn)策略

    MD5的算法在RFC1321中實(shí)際上已經(jīng)提供了C的實(shí)現(xiàn),我們其實(shí)馬上就能想到,至少有兩種用Java實(shí)現(xiàn)它的方法,第一種是,用Java語(yǔ)言重新寫整個(gè)算法,或者再說(shuō)簡(jiǎn)單點(diǎn)就是把C程序改寫成Java程序。第二種是,用JNI(Java Native Interface)來(lái)實(shí)現(xiàn),核心算法仍然用這個(gè)C程序,用Java類給它包個(gè)殼。

    但我個(gè)人認(rèn)為,JNI應(yīng)該是Java為了解決某類問題時(shí)的沒有辦法的辦法(比如與操作系統(tǒng)或I/O設(shè)備密切相關(guān)的應(yīng)用),同時(shí)為了提供和其它語(yǔ)言的互操作性的一個(gè)手段。使用JNI帶來(lái)的最大問題是引入了平臺(tái)的依賴性,打破了SUN所鼓吹的“一次編寫到處運(yùn)行”的Java好處。因此,我決定采取第一種方法,一來(lái)和大家一起嘗試一下“一次編寫到處運(yùn)行”的好處,二來(lái)檢驗(yàn)一下Java 2現(xiàn)在對(duì)于比較密集的計(jì)算的效率問題。





    回頁(yè)首


    實(shí)現(xiàn)過程

    限于這篇文章的篇幅,同時(shí)也為了更多的讀者能夠真正專注于問題本身,我不想就某一種Java集成開發(fā)環(huán)境來(lái)介紹這個(gè)Java Bean的制作過程,介紹一個(gè)方法時(shí)我發(fā)現(xiàn)步驟和命令很清晰,我相信有任何一種Java集成環(huán)境三天以上經(jīng)驗(yàn)的讀者都會(huì)知道如何把這些代碼在集成環(huán)境中編譯和運(yùn)行。用集成環(huán)境講述問題往往需要配很多屏幕截圖,這也是我一直對(duì)集成環(huán)境很頭疼的原因。我使用了一個(gè)普通的文本編輯器,同時(shí)使用了Sun公司標(biāo)準(zhǔn)的JDK 1.3.0 for Windows NT。

    其實(shí)把C轉(zhuǎn)換成Java對(duì)于一個(gè)有一定C語(yǔ)言基礎(chǔ)的程序員并不困難,這兩個(gè)語(yǔ)言的基本語(yǔ)法幾乎完全一致.我大概花了一個(gè)小時(shí)的時(shí)間完成了代碼的轉(zhuǎn)換工作,我主要作了下面幾件事:

    1. 把必須使用的一些#define的宏定義變成Class中的final static,這樣保證在一個(gè)進(jìn)程空間中的多個(gè)Instance共享這些數(shù)據(jù)
    2. 刪去了一些無(wú)用的#if define,因?yàn)槲抑魂P(guān)心MD5,這個(gè)推薦的C實(shí)現(xiàn)同時(shí)實(shí)現(xiàn)了MD2 MD3和 MD4,而且有些#if define還和C不同編譯器有關(guān)
    3. 將一些計(jì)算宏轉(zhuǎn)換成final static 成員函數(shù)。
    4. 所有的變量命名與原來(lái)C實(shí)現(xiàn)中保持一致,在大小寫上作一些符合Java習(xí)慣的變化,計(jì)算過程中的C函數(shù)變成了private方法(成員函數(shù))。
    5. 關(guān)鍵變量的位長(zhǎng)調(diào)整
    6. 定義了類和方法

    需要注意的是,很多早期的C編譯器的int類型是16 bit的,MD5使用了unsigned long int,并認(rèn)為它是32bit的無(wú)符號(hào)整數(shù)。而在Java中int是32 bit的,long是64 bit的。在MD5的C實(shí)現(xiàn)中,使用了大量的位操作。這里需要指出的一點(diǎn)是,盡管Java提供了位操作,由于Java沒有unsigned類型,對(duì)于右移位操作多提供了一個(gè)無(wú)符號(hào)右移:>>>,等價(jià)于C中的 >> 對(duì)于unsigned 數(shù)的處理。

    因?yàn)镴ava不提供無(wú)符號(hào)數(shù)的運(yùn)算,兩個(gè)大int數(shù)相加就會(huì)溢出得到一個(gè)負(fù)數(shù)或異常,因此我將一些關(guān)鍵變量在Java中改成了long類型(64bit)。我個(gè)人認(rèn)為這比自己去重新定義一組無(wú)符號(hào)數(shù)的類同時(shí)重載那些運(yùn)算符要方便,同時(shí)效率高很多并且代碼也易讀,OO(Object Oriented)的濫用反而會(huì)導(dǎo)致效率低下。

    限于篇幅,這里不再給出原始的C代碼,有興趣對(duì)照的讀者朋友可以去看RFC 1321。 MD5.java源代碼





    回頁(yè)首


    測(cè)試

    在RFC 1321中,給出了Test suite用來(lái)檢驗(yàn)?zāi)愕膶?shí)現(xiàn)是否正確:

    MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
                MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
                MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
                MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
                MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
                ……
                

    這些輸出結(jié)果的含義是指:空字符串””的MD5值是d41d8cd98f00b204e9800998ecf8427e,字符串”a”的MD5值是
    0cc175b9c0f1b6a831c399e269772661……
    編譯并運(yùn)行我們的程序:

                javac –Cd . MD5.java
                java beartool.MD5
                

    為了將來(lái)不與別人的同名程序沖突,我在我的程序的第一行使用了package beartool;

    因此編譯命令 javac ?Cd . MD5.java 命令在我們的工作目錄下自動(dòng)建立了一個(gè) beartool 目錄,目錄下放著編譯成功的 MD5.class

    我們將得到和Test suite同樣的結(jié)果。當(dāng)然還可以繼續(xù)測(cè)試你感興趣的其它MD5變換,例如:

                java beartool.MD5 1234
                

    將給出1234的MD5值。

    可能是我的計(jì)算機(jī)知識(shí)是從Apple II和Z80單板機(jī)開始的,我對(duì)大寫十六進(jìn)制代碼有偏好,如果您想使用小寫的Digest String只需要把byteHEX函數(shù)中的A、B、C、D、E、F改成a、b、 c、d、e、f就可以了。

    MD5據(jù)稱是一種比較耗時(shí)的計(jì)算,我們的Java版MD5一閃就算出來(lái)了,沒遇到什么障礙,而且用肉眼感覺不出來(lái)Java版的MD5比C版的慢。

    為了測(cè)試它的兼容性,我把這個(gè)MD5.class文件拷貝到我的另一臺(tái)Linux+IBM JDK 1.3的機(jī)器上,執(zhí)行后得到同樣結(jié)果,確實(shí)是“一次編寫到處運(yùn)行了”。





    回頁(yè)首


    Java Bean簡(jiǎn)述

    現(xiàn)在,我們已經(jīng)完成并簡(jiǎn)單測(cè)試了這個(gè)Java Class,我們文章的標(biāo)題是做一個(gè)Java Bean。

    其實(shí)普通的Java Bean很簡(jiǎn)單,并不是什么全新的或偉大的概念,就是一個(gè)Java的Class,盡管 Sun規(guī)定了一些需要實(shí)現(xiàn)的方法,但并不是強(qiáng)制的。而EJB(Enterprise Java Bean)無(wú)非規(guī)定了一些必須實(shí)現(xiàn)(非常類似于響應(yīng)事件)的方法,這些方法是供EJB Container使用(調(diào)用)的。

    在一個(gè)Java Application或Applet里使用這個(gè)bean非常簡(jiǎn)單,最簡(jiǎn)單的方法是你要使用這個(gè)類的源碼工作目錄下建一個(gè)beartool目錄,把這個(gè)class文件拷貝進(jìn)去,然后在你的程序中import beartool.MD5就可以了。最后打包成.jar或.war是保持這個(gè)相對(duì)的目錄關(guān)系就行了。

    Java還有一個(gè)小小的好處是你并不需要摘除我們的MD5類中那個(gè)main方法,它已經(jīng)是一個(gè)可以工作的Java Bean了。Java有一個(gè)非常大的優(yōu)點(diǎn)是她允許很方便地讓多種運(yùn)行形式在同一組代碼中共存,比如,你可以寫一個(gè)類,它即是一個(gè)控制臺(tái)Application和GUI Application,同時(shí)又是一個(gè)Applet,同時(shí)還是一個(gè)Java Bean,這對(duì)于測(cè)試、維護(hù)和發(fā)布程序提供了極大的方便,這里的測(cè)試方法main還可以放到一個(gè)內(nèi)部類中。

    這里講述了把測(cè)試和示例代碼放在一個(gè)內(nèi)部靜態(tài)類的好處,是一種不錯(cuò)的工程化技巧和途徑。





    回頁(yè)首


    把Java Bean裝到JSP里

    正如我們?cè)诒疚拈_頭講述的那樣,我們對(duì)這個(gè)MD5 Bean的應(yīng)用是基于一個(gè)用戶管理,這里我們假設(shè)了一個(gè)虛擬社區(qū)的用戶login過程,用戶的信息保存在數(shù)據(jù)庫(kù)的個(gè)名為users的表中。這個(gè)表有兩個(gè)字段和我們的這個(gè)例子有關(guān),userid :char(20)和pwdmd5 :char(32),userid是這個(gè)表的Primary Key,pwdmd5保存密碼的MD5串,MD5值是一個(gè)128bit的大整數(shù),表示成16進(jìn)制的ASCII需要32個(gè)字符。

    這里給出兩個(gè)文件, login.html是用來(lái)接受用戶輸入的form, login.jsp 用來(lái)模擬使用MD5 Bean的login過程。

    為了使我們的測(cè)試環(huán)境簡(jiǎn)單起見,我們?cè)贘SP中使用了JDK內(nèi)置的JDBC-ODBC Bridge Driver,community是ODBC的DSN的名字,如果你使用其它的JDBC Driver,替換掉login.jsp中的
    Connection con= DriverManager.getConnection("jdbc:odbc:community", "", "");

    即可。

    login.jsp的工作原理很簡(jiǎn)單,通過post接收用戶輸入的UserID和Password,然后將Password變換成MD5串,然后在users表中尋找UserID和pwdmd5,因?yàn)閁serID是users表的Primary Key,如果變換后的pwdmd5與表中的記錄不符,那么SQL查詢會(huì)得到一個(gè)空的結(jié)果集。

    這里需要簡(jiǎn)單介紹的是,使用這個(gè)Bean只需要在你的JSP應(yīng)用程序的WEB-INF/classes下建立一個(gè)beartool目錄,然后將MD5.class拷貝到那個(gè)目錄下就可以了。如果你使用一些集成開發(fā)環(huán)境,請(qǐng)參考它們的deploy工具的說(shuō)明。在JSP使用一個(gè)java Bean關(guān)鍵的一句聲明是程序中的第2行:

    <jsp:useBean id='oMD5' scope='request' class='beartool.MD5'/>

    這是所有JSP規(guī)范要求JSP容器開發(fā)者必須提供的標(biāo)準(zhǔn)Tag。

    id=實(shí)際上是指示JSP Container創(chuàng)建Bean的實(shí)例時(shí)用的實(shí)例變量名。在后面的<%和%>之間的Java程序中,你可以引用它。在程序中可以看到,通過 pwdmd5=oMD5.getMD5ofStr (password) 引用了我們的MD5 Java Bean提供的唯一一個(gè)公共方法: getMD5ofStr。

    Java Application Server執(zhí)行.JSP的過程是先把它預(yù)編譯成.java(那些Tag在預(yù)編譯時(shí)會(huì)成為java語(yǔ)句),然后再編譯成.class。這些都是系統(tǒng)自動(dòng)完成和維護(hù)的,那個(gè).class也稱為Servlet。當(dāng)然,如果你愿意,你也可以幫助Java Application Server去干本該它干的事情,自己直接去寫Servlet,但用Servlet去輸出HTML那簡(jiǎn)直是回到了用C寫CGI程序的惡夢(mèng)時(shí)代。

    如果你的輸出是一個(gè)復(fù)雜的表格,比較方便的方法我想還是用一個(gè)你所熟悉的HTML編輯器編寫一個(gè)“模板”,然后在把JSP代碼“嵌入”進(jìn)去。盡管這種JSP代碼被有些專家指責(zé)為“空心粉”,它的確有個(gè)缺點(diǎn)是代碼比較難管理和重復(fù)使用,但是程序設(shè)計(jì)永遠(yuǎn)需要的就是這樣的權(quán)衡。我個(gè)人認(rèn)為,對(duì)于中、小型項(xiàng)目,比較理想的結(jié)構(gòu)是把數(shù)據(jù)表示(或不嚴(yán)格地稱作WEB界面相關(guān))的部分用JSP寫,和界面不相關(guān)的放在Bean里面,一般情況下是不需要直接寫Servlet的。

    如果你覺得這種方法不是非常的OO(Object Oriented),你可以繼承(extends)它一把,再寫一個(gè)bean把用戶管理的功能包進(jìn)去。





    回頁(yè)首


    到底能不能兼容?

    我測(cè)試了三種Java應(yīng)用服務(wù)器環(huán)境,Resin 1.2.3、Sun J2EE 1.2、IBM WebSphere 3.5,所幸的是這個(gè)Java Bean都沒有任何問題,原因其實(shí)是因?yàn)樗鼉H僅是個(gè)計(jì)算程序,不涉及操作系統(tǒng),I/O設(shè)備。其實(shí)用其它語(yǔ)言也能簡(jiǎn)單地實(shí)現(xiàn)它的兼容性的,Java的唯一優(yōu)點(diǎn)是,你只需提供一個(gè)形態(tài)的運(yùn)行碼就可以了。請(qǐng)注意“形態(tài)”二字,現(xiàn)在很多計(jì)算結(jié)構(gòu)和操作系統(tǒng)除了語(yǔ)言本身之外都定義了大量的代碼形態(tài),很簡(jiǎn)單的一段C語(yǔ)言核心代碼,轉(zhuǎn)換成不同形態(tài)要考慮很多問題,使用很多工具,同時(shí)受很多限制,有時(shí)候?qū)W習(xí)一種新的“形態(tài)”所花費(fèi)的精力可能比解決問題本身還多。比如光Windows就有EXE、Service、的普通DLL、COM DLL以前還有OCX等等等等,在Unix上雖說(shuō)要簡(jiǎn)單一些,但要也要提供一個(gè).h定義一大堆宏,還要考慮不同平臺(tái)編譯器版本的位長(zhǎng)度問題。我想這是Java對(duì)我來(lái)說(shuō)的一個(gè)非常重要的魅力吧。

    login.html代碼:
    <html>
    <head>
    <title>Login</title>
    </head>
    <body>
    <form method="POST" action="login.jsp">
      
    <p>UserID:<input type="text" name="UserID" size="20">
      Password:
    <input type="password" name="Password" size="20"></p>
      
    <p><input type="submit" value="Login" name="Login"></p>
    </form>
    </body>
    </html>



    login.jsp代碼:
    <%@ page language='java' %>
    <jsp:useBean id='oMD5' scope='request' class='beartool.MD5'/>
     
    <%@ page import='java.util.*'%>
    <%@ page import='java.sql.*'%>
    <html>
    <body>
    <pre>
    <%
      
    String userid = request.getParameter("UserID");  //接受UserID
      
    String password = request.getParameter("Password"); //接受Password
      
    String pwdmd5 = oMD5.getMD5ofStr(password);  //變換密碼
      PrintWriter rp 
    = response.getWriter();
      Class.forName(
    "sun.jdbc.odbc.JdbcOdbcDriver");
      Connection con 
    = DriverManager.getConnection("jdbc:odbc:community""""");
      Statement stmt 
    = con.createStatement();                           
      ResultSet rs 
    = stmt.executeQuery("select * from users where userID ='"
    +userid+"' and pwdmd5= '" + pwdmd5+"'" );
      
    if (rs.next()) 
        {
          rp.print(
    "Login OK");
       }
      
    else
        {
          rp.print(
    "Login Fail");
        }
      stmt.close();
      con.close();
    %>



    posted on 2008-01-30 15:21 lk 閱讀(755) 評(píng)論(0)  編輯  收藏 所屬分類: j2se
    主站蜘蛛池模板: 亚洲AV色欲色欲WWW| 亚洲高清视频一视频二视频三| 中文亚洲成a人片在线观看| 国产亚洲精品AAAA片APP| 国产黄色片在线免费观看| 蜜芽亚洲av无码一区二区三区| 午夜神器成在线人成在线人免费| 亚洲色丰满少妇高潮18p| 日韩在线免费电影| 美女被羞羞网站免费下载| 亚洲性久久久影院| 国产一区二区三区免费| 亚洲男人第一av网站| 美丽的姑娘免费观看在线播放| 亚洲婷婷第一狠人综合精品| 扒开双腿猛进入爽爽免费视频 | 久久99亚洲综合精品首页| 成人免费ā片在线观看| 夜夜亚洲天天久久| 成人免费看片又大又黄| 免费无码专区毛片高潮喷水 | 国产特黄一级一片免费| 亚洲AV中文无码乱人伦下载 | 色老头永久免费网站| 亚洲av无码专区在线观看下载| 免费吃奶摸下激烈视频| a毛片在线免费观看| 亚洲无人区视频大全| 国产精品免费视频播放器| 两个人看的www免费视频| 亚洲av专区无码观看精品天堂| 可以免费观看一级毛片黄a| a级成人免费毛片完整版| 国产精品亚洲精品青青青| 亚洲国产中文v高清在线观看| 久久国产乱子精品免费女| 亚洲偷自拍另类图片二区| 亚洲午夜无码久久久久| 无人在线观看免费高清视频 | 亚洲AV无码成人专区片在线观看| 国产一精品一AV一免费孕妇|