PIXNET Logo登入

楊 bey kuen的部落格

跳到主文

歡迎光臨楊 bey kuen在痞客邦的小天地

部落格全站分類:

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 3月 31 週二 200910:16
  • Hibernate 配置 (三)

為了方便取得SessionFactory實例,可撰寫一個test.com.util .HibernateUtil類別:

package test.com.util;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    static {

        try {

            sessionFactory = new Configuration().configure().buildSessionFactory();

        } catch (Throwable ex) {

            throw new ExceptionInInitializerError(ex);

        }

    }

    public static SessionFactory getSessionFactory() {

        return sessionFactory;

    }

    public static void shutdown() {

        getSessionFactory().close();

    }

}


接下來撰寫一個測試的程式test.com.web.TestAction.java:

package test.com.web;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionMapping;

import org.apache.struts.action.ActionForward;

import test.com.delegate.TestDelegate;

import test.com.model.UserModel;

 

public class TestAction extends org.apache.struts.action.Action {

   

    public ActionForward execute(ActionMapping mapping, ActionForm form,

            HttpServletRequest request, HttpServletResponse response)

            throws Exception {

        /*

         *  declare variable

         */

        String forward = "testjsp";

        String name = null;

        String age = null;

        UserModel usermod = null;

 

        /*

         *  get value

         */

         name = request.getParameter("name");

         age = request.getParameter("age");

         usermod = new UserModel();

        /*

         *  call delegate

         */

         usermod.setName(name);

         usermod.setAge(age);

         TestDelegate.creatUser(usermod);

        /*

         *  set value

         */

         request.setAttribute("result", usermod);

        /*

         *  forward

         */

        return mapping.findForward(forward);

    }

}


test.com.delegate.TestDelegate.java:

package test.com.delegate;

 

import test.com.bo.TestBO;

import test.com.model.UserModel;

public class TestDelegate {

    public static void creatUser(UserModel user) {

        try {

            TestBO.creatUser(user);

        } catch (Exception ex) {

            //logger.error(ExceptionUtils.getStackTrace(ex));

        }

    }

}


test.com.bo.TestBO.java:

package test.com.bo;

import org.hibernate.tool.hbm2x.DAOExporter;

import test.com.dao.TestDAO;

import test.com.model.UserModel;

public class TestBO {

    public static void creatUser(UserModel user) {

        TestDAO.creatUser(user);

    }

}


test.com.dao.TestDAO.java:

package test.com.dao;

import org.hibernate.Session;

import org.hibernate.Transaction;

import test.com.model.UserModel;

import test.com.util.HibernateUtil;

public class TestDAO {

    // create

    public static void creatUser(UserModel user){

        // 開啟Session,相當於開啟JDBC的Connection

    Session session = HibernateUtil.getSessionFactory().openSession();

    // Transaction表示一組會話操作

    Transaction tx = session.beginTransaction();

    // 將物件映射至資料庫表格中儲存

    session.save (user);

    tx.commit ();

    session.close ();

    System.out.println ("新增資料OK!請先用MySQL觀看結果!");

    HibernateUtil.shutdown ();

    }

}

(繼續閱讀...)
文章標籤

楊 bey kuen 發表在 痞客邦 留言(0) 人氣(126)

  • 個人分類:JAVA小筆記
▲top
  • 3月 31 週二 200910:13
  • Hibernate 配置 (二)

開始Hibernate:

對於該Table建立一個對應的test.com.hbm.User.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="test.com.model.UserModel" table="user">

        <id column="id" name="id" type="java.lang.Integer">

            <generator class="native"/>

        </id>

        <property column="name" name="name" type="java.lang.String"/>

        <property column="age" name="age" type="java.lang.String"/>

    </class>

</hibernate-mapping>

 

對該test.com.hbm.User.hbm.xml,建立一個test.com.model.UserModel:

package test.com.model;

import java.io.Serializable;

public class UserModel implements Serializable {

    //ID

    private Integer id;

    //姓名

    private String name;

    //年齡

    private String age;

    public String getAge() {

        return age;

    }

    public void setAge(String age) {

        this.age = age;

    }

    public Integer getId() {

        return id;

    }

    public void setId(Integer id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }               }

接著必須在Hibernate配置文件hibernate.cfg.xml中指明映射文件的位置,如下加入映射文件位置:

<hibernate-configuration>

  <session-factory>

    ……………………….

    <!-- 以下設置物件與資料庫表格映射文件 -->

    <mapping resource="test/com/hbm/User.hbm.xml"/>

  </session-factory>

</hibernate-configuration>


(繼續閱讀...)
文章標籤

楊 bey kuen 發表在 痞客邦 留言(0) 人氣(62)

  • 個人分類:JAVA小筆記
▲top
  • 3月 31 週二 200910:04
  • Hibernate 配置 (一)

clip_image002說明:
    Hibernate 是「物件/關係對應」ORM(Object/Relational Mapping)的解決方案,簡單說就是物件對應關係,將JAVA中物件映射至關聯式資料庫中的表格, Hibernate 提供了這個過程中自動對應轉換的方案。
    Hibernate其底層對資料庫還是需依賴JDBC,所以您必須先取得JDBC驅動程式,以下將以MySQL為示範(MS-SQL留給各位去練習啦,其實換湯不換藥,原則上只要把JAR檔換掉URL改掉就行啦): 配置Hibernate:    可以到Hibernate官方網站(http://www.hibernate.org/)下載最新的Hibernate.jar,另有官方說明手冊可以參考,不過現在偷懶一下,我要在NetBeans IDE6.5中直接增加 Frameworks 的方式加上Hibernate。 請至Project的Properties中 Add a Frameworks,選擇Hibernate 3.2.5:

clip_image002 

增加後你可以在Project的Libraries中看到Hibernate所需的JAR檔:

clip_image001 

如果要手動加入Hibernate加入上列JAR檔,也可有相同效果。 

接著設置基本的Hibernate配置文件,可以使用XML或Properties檔案,NetBeans內建設定為xml檔,置放於Classpath路徑之中,配置如下:

…………………………………

<hibernate-configuration>

  <session-factory>

    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

    <!-- JDBC驅動程式 -->

    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

    <!-- JDBC URL -->

    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>

    <!-- 資料庫使用者 -->

    <property name="hibernate.connection.username">root</property>

    <!-- 資料庫密碼 -->

    <property name="hibernate.connection.password">root</property>

    <!-- 以下設置物件與資料庫表格映射文件 -->

  </session-factory></hibernate-configuration>

以上請於MySQL中建立一 [test] DB,至於資料庫的使用者與密碼請自行修改。 

請先在MySQL中建立一”test”table:

DROP TABLE IF EXISTS `test`.`new table`;

CREATE TABLE  `test`.`new table` (

  `id` int(10) unsigned NOT NULL auto_increment,

  `name` varchar(45) NOT NULL,

  `age` varchar(45) NOT NULL,

  PRIMARY KEY  (`id`)                  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

(繼續閱讀...)
文章標籤

楊 bey kuen 發表在 痞客邦 留言(0) 人氣(401)

  • 個人分類:JAVA小筆記
▲top
  • 3月 21 週六 200916:06
  • Hibernate + proxool comnnection Pool設定

  • 下載proxool,下載網址:http://proxool.sourceforge.net/
  • 解壓縮後將其中 proxool-0.9.1.jar、proxool-cglib.jar 放入專案中WEB-INF/libs(依各專案設定)
  • 於 hibernate.cfg.xml 同一層目錄下新增一XML檔 proxool.cfg.xml,檔案內容如下:
  • <?xml version="1.0" encoding="utf-8"?>
    <!-- the proxool configuration can be embedded within your own application's.
    Anything outside the "proxool" tag is ignored. -->
    <something-else-entirely>
        <proxool>
            <!-- Connection Pool的別名,但需與hibernate部分對應-->
            <alias>proxoolPool</alias>
            <!-- 讓proxool只能管理自己產生的連結 -->
            <driver-url>jdbc:mysql://localhost:3306/DBNAME</driver-url>
            <driver-class> com.mysql.jdbc.Driver </driver-class>
            <driver-properties>
                <property name="user" value=""/>
                <property name="password" value=""/>
            </driver-properties>
            <!-- proxool自動偵測各個連結狀態的時間間隔(毫秒),偵察到閒置的連結就即刻回收,超時的銷毀 (0.9.1版SOURCE為long所以建議不要設定,會以預設值為30秒作為銷毀時間)-->
            <house-keeping-sleep-time>90000</house-keeping-sleep-time>
            <!-- 指因未有閒置連結可以分配而在佇列中等候的最大連線數,超過這個連線數的用戶連線就不會被接受 -->
            <maximum-new-connections>20</maximum-new-connections>
            <!-- 最少保持的閒置連線數 -->
            <prototype-count>5</prototype-count>
            <!-- 允許最大連線數,超過了該連線數,再有請求時,就排在佇列中等候,最大的等待連線數由maximum-new-connections決定 -->
            <maximum-connection-count>100</maximum-connection-count>
            <!-- 最小連線數 -->
            <minimum-connection-count>10</minimum-connection-count>
            <!-- 對連線池的資料進行定時統計,1分鐘、五分鐘、一天分別作統計 -->
            <statistics>1m,15m,1d</statistics>
        </proxool>
    </something-else-entirely>
  • 修改 hibernate.cfg.xml 中設定
  • <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <!-- ProxoolConnection設定 -->
            <property name="connection.provider_class">org.hibernate.connection.ProxoolConnectionProvider</property>
            <!--這個名字要和Proxool.xml檔案中的別名要對應-->
            <property name="hibernate.proxool.pool_alias">proxoolPool</property>
            <!--對應上面建立的XML文件的名稱-->
            <property name="hibernate.proxool.xml">proxool.cfg.xml</property>
            <!-- 顯示實際操作資料庫時的SQL,上線時請改為false-->
            <property name="show_sql">true</property>
            <!-- 將顯示的SQL排版,方便觀看,上線時請改為false -->
            <property name="format_sql">true</property>
            <!-- SQL方言,這邊設定的是MySQL -->
            <property name="dialect">org.hibernate.dialect.MySQLDialect</property>                <!-- 對應資料庫設定文件 -->
            <mapping resource="delta/manage/news/hbm/NewsModel.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>
  • proxool內建監控畫面設定,只需於 web.xml 中增加下列設定即可在 http://localhost:8080/專案名稱/pool  中看到監控畫面
  • <!--proxool-->
        <servlet>
            <servlet-name>Admin</servlet-name>
            <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
        </servlet>     <servlet-mapping>
            <servlet-name>Admin</servlet-name>
            <url-pattern>/pool</url-pattern>
        </servlet-mapping>
    (繼續閱讀...)
    文章標籤

    楊 bey kuen 發表在 痞客邦 留言(0) 人氣(537)

    • 個人分類:JAVA小筆記
    ▲top
    • 3月 19 週四 200911:05
    • 17歲林冠廷 琴揚俄羅斯

    f_184907_1
    17歲林冠廷 琴揚俄羅斯
    2009/03/18
    【聯合報╱記者周美惠/台北報導】

    f_184907_1 
    17歲的林冠廷(右)參加俄國鋼琴家Vladimir Viardo為青少年所舉辦的鋼琴大賽,榮獲第二名。 圖/林福進提供
    曾贏得遠東銀行與本報主辦「送你一桶金」的得主、年僅17歲的林冠廷,最近在烏克蘭參加享譽國際的俄國鋼琴家Vladimir Viardo為青少年所舉辦的鋼琴大賽,獲第二名及600美元獎金。

    林冠廷4歲開始學琴,從小在音樂班名列前茅的他,年紀輕輕即立志走專業鋼琴家這條路。3年前,他考上俄國莫斯科Gnesin音樂院,留俄期間表現優異,常獲學校表揚及獎學金獎勵,並曾多次受邀在莫斯科音樂廳演出。

    此次獲獎,主辦此獎的鋼琴家Vladimir Viardo特別讚賞林冠廷把柴可夫斯基帶俄羅斯風的詼諧曲彈奏得「非常具俄國風味」。Viardo出身烏克蘭,雖已入籍美國,仍心繫故里,在烏克蘭舉辦以他為名的國際鋼琴大賽,參賽選手一半是烏克蘭好手,另一半來自世界各國。

    今年約有50名青少年分兩組參加這項大賽。林冠廷是他參加組別最小的選手,同組其他選手平均大他兩歲以上。這回勝出的第一名較林冠廷年長4歲,她實力超強,讓林冠廷覺得雖敗猶榮。

    林冠廷的媽媽一路陪伴他在異鄉求學、參賽,此次獲獎,她最感念的是「一桶金」。去年夏天,林冠廷返台,因媽媽覺得錢景周報舉辦的「送你一桶金」活動很有趣,就與他和妹妹一起試著猜金額,結果林冠廷猜的金額最接近答案,喜獲9萬餘元大獎。

    他們返回生活費奇高無比的莫斯科後,沒料到房東竟將房租調漲為兩倍(約10萬台幣),幸好有「一桶金」為他們解了燃眉之急,讓林媽媽直呼這是「上天派來幫助我們的天使」。

    (繼續閱讀...)
    文章標籤

    楊 bey kuen 發表在 痞客邦 留言(0) 人氣(95)

    • 個人分類:音樂
    ▲top
    • 3月 18 週三 200912:36
    • 介紹一篇關於session的好文章,寫的很詳細

    目錄:
    一、術語session
    二、HTTP協議與狀態保持
    三、理解cookie機制
    四、理解session機制
    五、理解javax.servlet.http.HttpSession
    六、HttpSession常見問題
    七、跨應用程序的session共享
    八、總結
    參考文檔
    一、術語session
    在我的經驗裡,session這個詞被濫用的程度大概僅次於transaction,更加有趣的是transaction與session在某些語境下的含義是相同的。
    session,中文經常翻譯為會話,其本來的含義是指有始有終的一系列動作/消息,比如打電話時從拿起電話撥號到掛斷電話這中間的一系列過程可以稱之為一個 session。有時候我們可以看到這樣的話「在一個瀏覽器會話期間,...」,這裡的會話一詞用的就是其本義,是指從一個瀏覽器窗口打開到關閉這個期間 1。最混亂的是「用戶(客戶端)在一次會話期間」這樣一句話,它可能指用戶的一系列動作(一般情況下是同某個具體目的相關的一系列動作,比如從登錄到選購商品到結賬登出這樣一個網上購物的過程,有時候也被稱為一個transaction),然而有時候也可能僅僅是指一次連接,也有可能是指含義1,其中的差別只能靠上下文來推斷2。
    然而當session一詞與網絡協議相關聯時,它又往往隱含了「面向連接」和/或「保持狀態」這樣兩個含義, 「面向連接」指的是在通信雙方在通信之前要先建立一個通信的渠道,比如打電話,直到對方接了電話通信才能開始,與此相對的是寫信,在你把信發出去的時候你並不能確認對方的地址是否正確,通信渠道不一定能建立,但對發信人來說,通信已經開始了。「保持狀態」則是指通信的一方能夠把一系列的消息關聯起來,使得消息之間可以互相依賴,比如一個服務員能夠認出再次光臨的老顧客並且記得上次這個顧客還欠店裡一塊錢。這一類的例子有「一個TCP session」或者 「一個POP3 session」3。
    而到了web服務器蓬勃發展的時代,session在web開發語境下的語義又有了新的擴展,它的含義是指一類用來在客戶端與服務器之間保持狀態的解決方案4。有時候session也用來指這種解決方案的存儲結構,如「把xxx保存在session 裡」5。由於各種用於web開發的語言在一定程度上都提供了對這種解決方案的支持,所以在某種特定語言的語境下,session也被用來指代該語言的解決方案,比如經常把Java裡提供的javax.servlet.http.HttpSession簡稱為session6。
    鑒於這種混亂已不可改變,本文中session一詞的運用也會根據上下文有不同的含義,請大家注意分辨。
    在本文中,使用中文「瀏覽器會話期間」來表達含義1,使用「session機制」來表達含義4,使用「session」表達含義5,使用具體的「HttpSession」來表達含義6
    二、HTTP協議與狀態保持
    HTTP 協議本身是無狀態的,這與HTTP協議本來的目的是相符的,客戶端只需要簡單的向服務器請求下載某些文件,無論是客戶端還是服務器都沒有必要紀錄彼此過去的行為,每一次請求之間都是獨立的,好比一個顧客和一個自動售貨機或者一個普通的(非會員制)大賣場之間的關係一樣。
    然而聰明(或者貪心?)的人們很快發現如果能夠提供一些按需生成的動態信息會使web變得更加有用,就像給有線電視加上點播功能一樣。這種需求一方面迫使HTML逐步添加了表單、腳本、DOM等客戶端行為,另一方面在服務器端則出現了CGI規範以響應客戶端的動態請求,作為傳輸載體的HTTP協議也添加了文件上載、 cookie這些特性。其中cookie的作用就是為了解決HTTP協議無狀態的缺陷所作出的努力。至於後來出現的session機制則是又一種在客戶端與服務器之間保持狀態的解決方案。
    讓我們用幾個例子來描述一下cookie和session機制之間的區別與聯繫。筆者曾經常去的一家咖啡店有喝5杯咖啡免費贈一杯咖啡的優惠,然而一次性消費5杯咖啡的機會微乎其微,這時就需要某種方式來紀錄某位顧客的消費數量。想像一下其實也無外乎下面的幾種方案:
    1、該店的店員很厲害,能記住每位顧客的消費數量,只要顧客一走進咖啡店,店員就知道該怎麼對待了。這種做法就是協議本身支持狀態。
    2、發給顧客一張卡片,上面記錄著消費的數量,一般還有個有效期限。每次消費時,如果顧客出示這張卡片,則此次消費就會與以前或以後的消費相聯繫起來。這種做法就是在客戶端保持狀態。
    3、發給顧客一張會員卡,除了卡號之外什麼信息也不紀錄,每次消費時,如果顧客出示該卡片,則店員在店裡的紀錄本上找到這個卡號對應的紀錄添加一些消費信息。這種做法就是在服務器端保持狀態。
    由於HTTP協議是無狀態的,而出於種種考慮也不希望使之成為有狀態的,因此,後面兩種方案就成為現實的選擇。具體來說cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在服務器端保持狀態的方案。同時我們也看到,由於採用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助於cookie機制來達到保存標識的目的,但實際上它還有其他選擇。
    三、理解cookie機制
    cookie機制的基本原理就如上面的例子一樣簡單,但是還有幾個問題需要解決:「會員卡」如何分發;「會員卡」的內容;以及客戶如何使用「會員卡」。
    正統的cookie分發是通過擴展HTTP協議來實現的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie。
    而cookie 的使用是由瀏覽器按照一定的原則在後台自動發送給服務器的。瀏覽器檢查所有存儲的cookie,如果某個cookie所聲明的作用範圍大於等於將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發送給服務器。意思是麥當勞的會員卡只能在麥當勞的店裡出示,如果某家分店還發行了自己的會員卡,那麼進這家店的時候除了要出示麥當勞的會員卡,還要出示這家店的會員卡。
    cookie的內容主要包括:名字,值,過期時間,路徑和域。
    其中域可以指定某一個域比如.google.com,相當於總店招牌,比如寶潔公司,也可以指定一個域下的具體某台機器比如www.google.com或者froogle.google.com,可以用飄柔來做比。
    路徑就是跟在域名後面的URL路徑,比如/或者/foo等等,可以用某飄柔專櫃做比。
    路徑與域合在一起就構成了cookie的作用範圍。
    如果不設置過期時間,則表示這個cookie的生命期為瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。這種生命期為瀏覽器會話期的 cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內存裡,當然這種行為並不是規範規定的。如果設置了過期時間,瀏覽器就會把cookie保存到硬盤上,關閉後再次打開瀏覽器,這些cookie仍然有效直到超過設定的過期時間。
    存儲在硬盤上的cookie 可以在不同的瀏覽器進程間共享,比如兩個IE窗口。而對於保存在內存裡的cookie,不同的瀏覽器有不同的處理方式。對於IE,在一個打開的窗口上按 Ctrl-N(或者從文件菜單)打開的窗口可以與原窗口共享,而使用其他方式新開的IE進程則不能共享已經打開的窗口的內存cookie;對於 Mozilla Firefox0.8,所有的進程和標籤頁都可以共享同樣的cookie。一般來說是用javascript的window.open打開的窗口會與原窗口共享內存cookie。瀏覽器對於會話cookie的這種只認cookie不認人的處理方式經常給採用session機制的web應用程序開發者造成很大的困擾。
    下面就是一個goolge設置cookie的響應頭的例子
    HTTP/1.1 302 Found
    Location: http://www.google.com/intl/zh-CN/
    Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
    Content-Type: text/html
    這是使用HTTPLook這個HTTP Sniffer軟件來俘獲的HTTP通訊紀錄的一部分
    瀏覽器在再次訪問goolge的資源時自動向外發送cookie
    使用Firefox可以很容易的觀察現有的cookie的值
    使用HTTPLook配合Firefox可以很容易的理解cookie的工作原理。
    IE也可以設置在接受cookie前詢問
    這是一個詢問接受cookie的對話框。
    四、理解session機制
    session機制是一種服務器端的機制,服務器使用一種類似於散列表的結構(也可能就是使用散列表)來保存信息。
    當程序需要為某個客戶端的請求創建一個session的時候,服務器首先檢查這個客戶端的請求裡是否已包含了一個session標識 - 稱為 session id,如果已包含一個session id則說明以前已經為此客戶端創建過session,服務器就按照session id把這個 session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個 session id將被在本次響應中返回給客戶端保存。
    保存這個session id的方式可以採用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發揮給服務器。一般這個cookie的名字都是類似於SEEESIONID,而。比如weblogic對於web應用程序生成的cookie,JSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是 JSESSIONID。
    由於cookie可以被人為的禁止,必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器。經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的後面,附加方式也有兩種,一種是作為URL路徑的附加信息,表現形式為http://...../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
    另一種是作為查詢字符串附加在URL後面,表現形式為http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
    這兩種方式對於用戶來說是沒有區別的,只是服務器在解析的時候處理的方式不同,採用第一種方式也有利於把session id的信息和正常程序參數區分開來。
    為了在整個交互過程中始終保持狀態,就必須在每個客戶端可能請求的路徑後面都包含這個session id。
    另一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把session id傳遞回服務器。比如下面的表單
    <form name="testform" action="/xxx">
    <input type="text">
    </form>
    在被傳遞給客戶端之前將被改寫成
    <form name="testform" action="/xxx">
    <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
    <input type="text">
    </form>
    這種技術現在已較少應用,筆者接觸過的很古老的iPlanet6(SunONE應用服務器的前身)就使用了這種技術。
    實際上這種技術可以簡單的用對action應用URL重寫來代替。
    在談論session機制的時候,常常聽到這樣一種誤解「只要關閉瀏覽器,session就消失了」。其實可以想像一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易刪除顧客的資料。對session來說也是一樣的,除非程序通知服務器刪除一個session,否則服務器會一直保留,程序一般都是在用戶做log off的時候發個指令去刪除session。然而瀏覽器從來不會主動在關閉之前通知服務器它將要關閉,因此服務器根本不會有機會知道瀏覽器已經關閉,之所以會有這種錯覺,是大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器後這個 session id就消失了,再次連接服務器時也就無法找到原來的session。如果服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的HTTP請求頭,把原來的session id發送給服務器,則再次打開瀏覽器仍然能夠找到原來的session。
    恰恰是由於關閉瀏覽器不會導致session被刪除,迫使服務器為seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就可以認為客戶端已經停止了活動,才會把session刪除以節省存儲空間。
    五、理解javax.servlet.http.HttpSession
    HttpSession是Java平台對session機制的實現規範,因為它僅僅是個接口,具體到每個web應用服務器的提供商,除了對規範支持之外,仍然會有一些規範裡沒有規定的細微差異。這裡我們以BEA的Weblogic Server8.1作為例子來演示。
    首先,Weblogic Server提供了一系列的參數來控制它的HttpSession的實現,包括使用cookie的開關選項,使用URL重寫的開關選項,session持久化的設置,session失效時間的設置,以及針對cookie的各種設置,比如設置cookie的名字、路徑、域, cookie的生存時間等。
    一般情況下,session都是存儲在內存裡,當服務器進程被停止或者重啟的時候,內存裡的session也會被清空,如果設置了session的持久化特性,服務器就會把session保存到硬盤上,當服務器進程重新啟動或這些信息將能夠被再次使用, Weblogic Server支持的持久性方式包括文件、數據庫、客戶端cookie保存和複製。
    複製嚴格說來不算持久化保存,因為session實際上還是保存在內存裡,不過同樣的信息被複製到各個cluster內的服務器進程中,這樣即使某個服務器進程停止工作也仍然可以從其他進程中取得session。
    cookie生存時間的設置則會影響瀏覽器生成的cookie是否是一個會話cookie。默認是使用會話cookie。有興趣的可以用它來試驗我們在第四節裡提到的那個誤解。
    cookie的路徑對於web應用程序來說是一個非常重要的選項,Weblogic Server對這個選項的默認處理方式使得它與其他服務器有明顯的區別。後面我們會專題討論。
    關於session的設置參考[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869
    六、HttpSession常見問題
    (在本小節中session的含義為5和6的混合)
    1、session在何時被創建
    一個常見的誤解是以為session在有客戶端訪問時就被創建,然而事實是直到某server端程序調用 HttpServletRequest.getSession(true)這樣的語句時才被創建,注意如果JSP沒有顯示的使用 <% @page session="false"%> 關閉session,則JSP文件在編譯成Servlet時將會自動加上這樣一條語句 HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的 session對象的來歷。
    由於session會消耗內存資源,因此,如果不打算使用session,應該在所有的JSP中關閉它。
    2、session何時被刪除
    綜合前面的討論,session在下列情況下被刪除a.程序調用HttpSession.invalidate();或b.距離上一次收到客戶端發送的session id時間間隔超過了session的超時設置;或c.服務器進程被停止(非持久session)
    3、如何做到在瀏覽器關閉時刪除session
    嚴格的講,做不到這一點。可以做一點努力的辦法是在所有的客戶端頁面裡使用javascript代碼window.oncolose來監視瀏覽器的關閉動作,然後向服務器發送一個請求來刪除session。但是對於瀏覽器崩潰或者強行殺死進程這些非常規手段仍然無能為力。
    4、有個HttpSessionListener是怎麼回事
    你可以創建這樣的listener去監控session的創建和銷毀事件,使得在發生這樣的事件時你可以做一些相應的工作。注意是session的創建和銷毀動作觸發listener,而不是相反。類似的與HttpSession有關的listener還有 HttpSessionBindingListener,HttpSessionActivationListener和 HttpSessionAttributeListener。
    5、存放在session中的對象必須是可序列化的嗎
    不是必需的。要求對象可序列化只是為了session能夠在集群中被複製或者能夠持久保存或者在必要時server能夠暫時把session交換出內存。在 Weblogic Server的session中放置一個不可序列化的對象在控制台上會收到一個警告。我所用過的某個iPlanet版本如果 session中有不可序列化的對象,在session銷毀時會有一個Exception,很奇怪。
    6、如何才能正確的應付客戶端禁止cookie的可能性
    對所有的URL使用URL重寫,包括超鏈接,form的action,和重定向的URL,具體做法參見[6]
    http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770
    7、開兩個瀏覽器窗口訪問應用程序會使用同一個session還是不同的session
    參見第三小節對cookie的討論,對session來說是只認id不認人,因此不同的瀏覽器,不同的窗口打開方式以及不同的cookie存儲方式都會對這個問題的答案有影響。
    8、如何防止用戶打開兩個瀏覽器窗口操作導致的session混亂
    這個問題與防止表單多次提交是類似的,可以通過設置客戶端的令牌來解決。就是在服務器每次生成一個不同的id返回給客戶端,同時保存在session裡,客戶端提交表單時必須把這個id也返回服務器,程序首先比較返回的id與保存在session裡的值是否一致,如果不一致則說明本次操作已經被提交過了。可以參看《J2EE核心模式》關於表示層模式的部分。需要注意的是對於使用javascript window.open打開的窗口,一般不設置這個id,或者使用單獨的id,以防主窗口無法操作,建議不要再window.open打開的窗口裡做修改操作,這樣就可以不用設置。
    9、為什麼在Weblogic Server中改變session的值後要重新調用一次session.setValue
    做這個動作主要是為了在集群環境中提示Weblogic Server session中的值發生了改變,需要向其他服務器進程複製新的session值。
    10、為什麼session不見了
    排除session正常失效的因素之外,服務器本身的可能性應該是微乎其微的,雖然筆者在iPlanet6SP1加若干補丁的Solaris版本上倒也遇到過;瀏覽器插件的可能性次之,筆者也遇到過3721插件造成的問題;理論上防火牆或者代理服務器在cookie處理上也有可能會出現問題。
    出現這一問題的大部分原因都是程序的錯誤,最常見的就是在一個應用程序中去訪問另外一個應用程序。我們在下一節討論這個問題。
    七、跨應用程序的session共享
    常常有這樣的情況,一個大項目被分割成若干小項目開發,為了能夠互不干擾,要求每個小項目作為一個單獨的web應用程序開發,可是到了最後突然發現某幾個小項目之間需要共享一些信息,或者想使用session來實現SSO(single sign on),在session中保存login的用戶信息,最自然的要求是應用程序間能夠訪問彼此的session。
    然而按照Servlet規範,session的作用範圍應該僅僅限於當前應用程序下,不同的應用程序之間是不能夠互相訪問對方的session的。各個應用服務器從實際效果上都遵守了這一規範,但是實現的細節卻可能各有不同,因此解決跨應用程序session共享的方法也各不相同。
    首先來看一下Tomcat是如何實現web應用程序之間session的隔離的,從 Tomcat設置的cookie路徑來看,它對不同的應用程序設置的cookie路徑是不同的,這樣不同的應用程序所用的session id是不同的,因此即使在同一個瀏覽器窗口裡訪問不同的應用程序,發送給服務器的session id也可以是不同的。
    根據這個特性,我們可以推測Tomcat中session的內存結構大致如下。
    筆者以前用過的iPlanet也採用的是同樣的方式,估計SunONE與iPlanet之間不會有太大的差別。對於這種方式的服務器,解決的思路很簡單,實際實行起來也不難。要麼讓所有的應用程序共享一個session id,要麼讓應用程序能夠獲得其他應用程序的session id。
    iPlanet中有一種很簡單的方法來實現共享一個session id,那就是把各個應用程序的cookie路徑都設為/(實際上應該是/NASApp,對於應用程序來講它的作用相當於根)。
    <session-info>
    <path>/NASApp</path>
    </session-info>
    需要注意的是,操作共享的session應該遵循一些編程約定,比如在session attribute名字的前面加上應用程序的前綴,使得 setAttribute("name", "neo")變成setAttribute("app1.name", "neo"),以防止命名空間衝突,導致互相覆蓋。
    在Tomcat中則沒有這麼方便的選擇。在Tomcat版本3上,我們還可以有一些手段來共享session。對於版本4以上的Tomcat,目前筆者尚未發現簡單的辦法。只能借助於第三方的力量,比如使用文件、數據庫、JMS或者客戶端cookie,URL參數或者隱藏字段等手段。
    我們再看一下Weblogic Server是如何處理session的。 
    從截屏畫面上可以看到Weblogic Server對所有的應用程序設置的cookie的路徑都是/,這是不是意味著在Weblogic Server中默認的就可以共享session了呢?然而一個小實驗即可證明即使不同的應用程序使用的是同一個session,各個應用程序仍然只能訪問自己所設置的那些屬性。這說明Weblogic Server中的session的內存結構可能如下
    對於這樣一種結構,在 session機制本身上來解決session共享的問題應該是不可能的了。除了借助於第三方的力量,比如使用文件、數據庫、JMS或者客戶端 cookie,URL參數或者隱藏字段等手段,還有一種較為方便的做法,就是把一個應用程序的session放到ServletContext中,這樣另外一個應用程序就可以從ServletContext中取得前一個應用程序的引用。示例代碼如下,
    應用程序A
    context.setAttribute("appA", session);
    應用程序B
    contextA = context.getContext("/appA");
    HttpSession sessionA = (HttpSession)contextA.getAttribute("appA");
    值得注意的是這種用法不可移植,因為根據ServletContext的JavaDoc,應用服務器可以處於安全的原因對於context.getContext("/appA");返回空值,以上做法在Weblogic Server 8.1中通過。
    那麼Weblogic Server為什麼要把所有的應用程序的cookie路徑都設為/呢?原來是為了SSO,凡是共享這個session的應用程序都可以共享認證的信息。一個簡單的實驗就可以證明這一點,修改首先登錄的那個應用程序的描述符weblogic.xml,把cookie路徑修改為/appA 訪問另外一個應用程序會重新要求登錄,即使是反過來,先訪問cookie路徑為/的應用程序,再訪問修改過路徑的這個,雖然不再提示登錄,但是登錄的用戶信息也會丟失。注意做這個實驗時認證方式應該使用FORM,因為瀏覽器和web服務器對basic認證方式有其他的處理方式,第二次請求的認證不是通過 session來實現的。具體請參看[7] secion 14.8 Authorization,你可以修改所附的示例程序來做這些試驗。
    八、總結
    session機制本身並不複雜,然而其實現和配置上的靈活性卻使得具體情況複雜多變。這也要求我們不能把僅僅某一次的經驗或者某一個瀏覽器,服務器的經驗當作普遍適用的經驗,而是始終需要具體情況具體分析。
    摘要:雖然session機制在web應用程序中被採用已經很長時間了,但是仍然有很多人不清楚session機制的本質,以至不能正確的應用這一技術。本文將詳細討論session的工作機制並且對在Java web application中應用session機制時常見的問題作出解答
    轉貼自:http://blog.e-happy.com.tw/article.asp?id=51
    (繼續閱讀...)
    文章標籤

    楊 bey kuen 發表在 痞客邦 留言(0) 人氣(22,811)

    • 個人分類:JAVA小筆記
    ▲top
    • 2月 04 週三 200916:03
    • Apache2.2 + SSL 配置

    Apache掛 SSL 一、預備檔案:          1. Apache_2.2.4-win32-openssl-0.9.8d.msi  <*重要的是注意1.和2.的openssl版本要相符*>          2. OpenSSL-0.9.8d_win32.rar          3. openssl.cnf 二、安裝Openssl、產生CA檔案:         1. 將OpenSSL-0.9.8d_win32.rar解壓縮,以解壓縮至 C:\Openssl為例,底下應該會有 \bin, \include, \lib, \ssl 四個資料夾和一個 openssl.cnf 檔。         2. 用另外抓取的 openssl.cnf(一、3.) 覆蓋掉原本的。         3. 用文字編輯器打開覆蓋後的 openssl.cnf,修改以下部份:*要注意"\\",不可以少打成"\"。             dir = ssl             certs = $dir\\certs             crl_dir = $dir\\crl             database = $dir\\index.txt             new_certs_dir = $dir             certificate = $dir\\cacert.pem             serial = $dir\\serial             crl = $dir\\crl.pem             private_key = $dir\\privkey.pem             RANDFILE = $dir\\privkey.rnd         4. 將 x509extensions 開頭的這一行註解掉。(前面加上#字號)         5. 在 C:\Openssl\ 下開啟新資料夾 ssl,並在其中新增 index.txt 及 serial 兩個檔案, serial用文字編輯器打開,輸入01,index.txt保持空白。         6. 將 \bin底下的檔案複製一份到 C:\Openssl\底下。(這是為了避免之後路徑的困擾)         7. 進入命令列模式,依序執行以下動作:             7-1: openssl genrsa -des3 -out ssl/ca.key 1024             7-2: openssl req -config openssl.cnf -new -key ssl/ca.key -out ssl/ca.csr             7-3: openssl x509 -days 3650 -req -signkey ssl/ca.key -in ssl/ca.csr -out ssl/ca.crt             7-4: openssl genrsa -out ssl/server.key 1024             7-5: openssl req -config openssl.cnf -new -key ssl/server.key -out ssl/server.csr openssl ca -config             7-6: openssl.cnf -days 3650 -cert ssl/ca.crt -keyfile ssl/ca.key -in ssl/server.csr -out ssl/server.crt             *在上列6個步驟裡面會要求輸入密碼、國碼(04)、國家、地區、公司名稱、單位、網站位址、Email。             *在 7-6步驟,會有兩個問題[y/n],都要選y.不然產生的server.crt會出錯,變成空檔案(Empty)。             *如果有error多半是路徑錯誤,稍微檢查一下指令做修正即可。         8. 將 7產生的檔案(整個ssl資料夾)複製到 C:/Appserv/Apache2.2/conf/ 底下。   三、修改httpd-ssl.conf:         1. 打開 C:\AppServ\Apache2.2\conf\extra\httpd-ssl.conf 檔案,修改部份如下:             DocumentRoot 網頁根目錄,比照httpd.conf下的DocumentRoot             ServerName Server位址:443             ServerAdmin Email             ErrorLog logs/error_log             TransferLog logs/access_log             ---             SSLCertificateFile conf/ssl/server.crt    <------crt存放目錄             SSLCertificateKeyFile conf/ssl/server.key   <------key存放目錄             SSLCertificateChainFile conf/ssl/ca.crt   <------中繼憑證存放目錄             ---             將SSLMutex default註解掉,改為SSLMutex none             ---             將所有沒有用雙引號包起來的絕對路徑加上雙引號,例如:             SSLSessionCache "shmcb:C:/AppServ/Apache2.2/logs/ssl_scache(512000)"             SSLCertificateFile "C:/AppServ/Apache2.2/conf/ssl/server.crt"             ---             將< VirtualHost >的標注部份改為             NameVirtualHost *:443             < VirtualHost *:443 >   五、修改httpd.conf:         1. 打開 C:\AppServ\Apache2.2\conf\httpd.conf檔案,修改部份如下:             把 LoadModule ssl_module modules/mod_ssl.so 的#註解拿掉             把 Include conf/extra/httpd-ssl.conf 的#註解拿掉   六、重新啟動Apache:       如果啟動過程中沒有出現錯誤,可以連 https://localhost 測試看看,應該就會出現要求憑證的認證畫面了。         *如果Apache啟動失敗,請檢查 error.log或到 Windows 事件檢視器確認是哪邊設定錯誤。
    (繼續閱讀...)
    文章標籤

    楊 bey kuen 發表在 痞客邦 留言(0) 人氣(180)

    • 個人分類:JAVA小筆記
    ▲top
    • 1月 20 週二 200913:38
    • JAVA日期時間顯示

    24小時制日期顯示:
    public class Datetime {
        public static void main(String args[]){
             java.util.Date current=new java.util.Date();
             java.text.SimpleDateFormat sdf=new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             String c=sdf.format(current);
             System.out.println(c);   
        }
    } 12小時制日期顯示: public class Datetime {
        public static void main(String args[]){
             java.util.Date current=new java.util.Date();
             java.text.SimpleDateFormat sdf=new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
             String c=sdf.format(current);
             System.out.println(c);
        }
    } 兩者區別:yyyy-MM-dd HH:mm:ss ;  yyyy-MM-dd hh:mm:ss 如下:

    字母

    日期或時間元素

    型態

    範例

    G

    Era標識符號         

    Text

    AD

    y

    年           

    Year 

    1996; 96

    M

    年中的月份

    Month

    July; Jul; 07

    w

    年中的周數         

    Number

    27 

    W

    月份中的周數

    Number

    2

    D

    年中的天數

    Number

    189

    d

    月份中的天數

    Number

    10

    F

    月份中的星期

    Number

    2

    E

    星期中的天數

    Text

    Tuesday; Tue

    a

    Am/pm 標記

    Text

    PM 

    H

    一天中的小時數(0-23)

    Number

    0

    k

    一天中的小時數(1-24)

    Number

    24

    K

    am/pm 中的小時數(0-11)

    Number

    0 

    h

    am/pm 中的小時數(1-12)

    Number

    12

    m

    小時中的分鐘數

    Number

    30

    s

    分鐘中的秒數

    Number

    55

    S

    毫秒數

    Number

    978

    z

    時區

    General time zone Pacific Standard Time; PST;

    GMT-08:00

    Z

    時區 RFC 822 time zone -0800 如果你解析RSS2.0 標準,其中/rss/item/pubDate的RFT標準格式為:Mon, 5 May 2008 00:01:00 EST 那麼對應的日期格式表示式為 E, d MMM yyyy HH:mm:ss z
    (繼續閱讀...)
    文章標籤

    楊 bey kuen 發表在 痞客邦 留言(0) 人氣(2,585)

    • 個人分類:JAVA小筆記
    ▲top
    • 1月 20 週二 200911:30
    • JAVA計時器

    Timer與TimerTask應用。利用  timer.schedule(new RemindTask() , now, minutes * 2 * 1000),來實現從程式啟動後每隔幾秒鐘執行一次應用程式,並限定執行幾次後程式自動停止,範例如下: package testjava; import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask; public class EggTimer {     private final Timer timer = new Timer();
        private final int minutes;
        public EggTimer(int minutes) {
            this.minutes = minutes;
        }     public void start() {
            Date now = new Date();
            timer.schedule(new RemindTask() , now, minutes * 2 * 1000);     }     class RemindTask extends TimerTask {
            int runtimer= 10;         public void run(){
                if (runtimer> 0){
                    System.out.println(runtimer+":Beep!  "+ new java.util.Date());
                    runtimer--;
                } else{
                    System.out.println(runtimer+" Time''s up!!  "+ new java.util.Date());
                    timer.cancel(); //call System.exit is the same to stop PGM
                    //System.exit(0);   //Stops the AWT thread (and everything else)
                }
            }
        }     public static void main(String[] args) throws Exception {
            System.out.println("開始時間:" + new java.util.Date());
            EggTimer eggTimer = new EggTimer(1);
            eggTimer.start();
        }
    } *********************************************************************** 範例二 : 每週日午夜零時執行一次
    /* class MainApplication */
    package sche.*;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask; public class MainApplication {
    public static void main(String[] args) {
    Timer timer = new Timer();
    Calendar date = Calendar.getInstance();
    date.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
    date.set(Calendar.HOUR, 0);
    date.set(Calendar.MINUTE, 0);
    date.set(Calendar.SECOND, 0);
    date.set(Calendar.MILLISECOND, 0);
    // 每週日午夜零時執行一次
    timer.schedule(new ReportGenerator(),date.getTime(),1000 * 60 * 60 * 24 * 7);
    }
    (繼續閱讀...)
    文章標籤

    楊 bey kuen 發表在 痞客邦 留言(0) 人氣(6,842)

    • 個人分類:JAVA小筆記
    ▲top
    • 1月 06 週二 200914:34
    • MD5 Java Script 版 原始碼

    var hex_chr = "0123456789abcdef";
    function rhex(num)
    {
    str = "";
    for(j = 0; j <= 3; j++)
    str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) +
    hex_chr.charAt((num >> (j * 8)) & 0x0F);
    return str;
    }
    /*
    * Convert a string to a sequence of 16-word blocks, stored as an array.
    * Append padding bits and the length, as described in the MD5 standard.
    */
    function str2blks_MD5(str)
    {
    nblk = ((str.length + 8) >> 6) + 1;
    blks = new Array(nblk * 16);
    for(i = 0; i < nblk * 16; i++) blks[i] = 0;
    for(i = 0; i < str.length; i++)
    blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
    blks[i >> 2] |= 0x80 << ((i % 4) * 8);
    blks[nblk * 16 - 2] = str.length * 8;
    return blks;
    }
    /*
    * Add integers, wrapping at 2^32. This uses 16-bit operations internally
    * to work around bugs in some JS interpreters.
    */
    function add(x, y)
    {
    var lsw = (x & 0xFFFF) + (y & 0xFFFF);
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return (msw << 16) | (lsw & 0xFFFF);
    }
    /*
    * Bitwise rotate a 32-bit number to the left
    */
    function rol(num, cnt)
    {
    return (num << cnt) | (num >>> (32 - cnt));
    }
    /*
    * These functions implement the basic operation for each round of the
    * algorithm.
    */
    function cmn(q, a, b, x, s, t)
    {
    return add(rol(add(add(a, q), add(x, t)), s), b);
    }
    function ff(a, b, c, d, x, s, t)
    {
    return cmn((b & c) | ((~b) & d), a, b, x, s, t);
    }
    function gg(a, b, c, d, x, s, t)
    {
    return cmn((b & d) | (c & (~d)), a, b, x, s, t);
    }
    function hh(a, b, c, d, x, s, t)
    {
    return cmn(b ^ c ^ d, a, b, x, s, t);
    }
    function ii(a, b, c, d, x, s, t)
    {
    return cmn(c ^ (b | (~d)), a, b, x, s, t);
    }
    /*
    * Take a string and return the hex representation of its MD5.
    */
    function md5(str)
    {
    x = str2blks_MD5(str);
    var a = 1732584193;
    var b = -271733879;
    var c = -1732584194;
    var d = 271733878;
    for(i = 0; i < x.length; i += 16)
    {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    a = ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = ff(c, d, a, b, x[i+ 2], 17, 606105819);
    b = ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = ff(d, a, b, c, x[i+ 5], 12, 1200080426);
    c = ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
    d = ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = ff(c, d, a, b, x[i+10], 17, -42063);
    b = ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = ff(a, b, c, d, x[i+12], 7 , 1804603682);
    d = ff(d, a, b, c, x[i+13], 12, -40341101);
    c = ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = ff(b, c, d, a, x[i+15], 22, 1236535329);
    a = gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = gg(c, d, a, b, x[i+11], 14, 643717713);
    b = gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = gg(d, a, b, c, x[i+10], 9 , 38016083);
    c = gg(c, d, a, b, x[i+15], 14, -660478335);
    b = gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = gg(a, b, c, d, x[i+ 9], 5 , 568446438);
    d = gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = gg(b, c, d, a, x[i+ 8], 20, 1163531501);
    a = gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = gg(c, d, a, b, x[i+ 7], 14, 1735328473);
    b = gg(b, c, d, a, x[i+12], 20, -1926607734);
    a = hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = hh(c, d, a, b, x[i+11], 16, 1839030562);
    b = hh(b, c, d, a, x[i+14], 23, -35309556);
    a = hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = hh(d, a, b, c, x[i+ 4], 11, 1272893353);
    c = hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = hh(a, b, c, d, x[i+13], 4 , 681279174);
    d = hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = hh(b, c, d, a, x[i+ 6], 23, 76029189);
    a = hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = hh(d, a, b, c, x[i+12], 11, -421815835);
    c = hh(c, d, a, b, x[i+15], 16, 530742520);
    b = hh(b, c, d, a, x[i+ 2], 23, -995338651);
    a = ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = ii(d, a, b, c, x[i+ 7], 10, 1126891415);
    c = ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = ii(a, b, c, d, x[i+12], 6 , 1700485571);
    d = ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = ii(c, d, a, b, x[i+10], 15, -1051523);
    b = ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
    d = ii(d, a, b, c, x[i+15], 10, -30611744);
    c = ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = ii(b, c, d, a, x[i+13], 21, 1309151649);
    a = ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = ii(c, d, a, b, x[i+ 2], 15, 718787259);
    b = ii(b, c, d, a, x[i+ 9], 21, -343485551);
    a = add(a, olda);
    b = add(b, oldb);
    c = add(c, oldc);
    d = add(d, oldd);
    }
    return rhex(a) + rhex(b) + rhex(c) + rhex(d);
    }
    (繼續閱讀...)
    文章標籤

    楊 bey kuen 發表在 痞客邦 留言(0) 人氣(49)

    • 個人分類:JAVA小筆記
    ▲top
    12...4»

    自訂側欄

    自訂側欄

    個人資訊

    楊 bey kuen
    暱稱:
    楊 bey kuen
    分類:
    好友:
    累積中
    地區:

    熱門文章

    • (22,811)介紹一篇關於session的好文章,寫的很詳細
    • (829)HowTo configure the C3P0 connection pool

    文章分類

    • 金融小筆記 (5)
    • SQL小筆記 (2)
    • 音樂 (1)
    • JAVA小筆記 (13)
    • 未分類文章 (1)

    最新文章

    • Hibernate 配置 (三)
    • Hibernate 配置 (二)
    • Hibernate 配置 (一)
    • Hibernate + proxool comnnection Pool設定
    • 17歲林冠廷 琴揚俄羅斯
    • 介紹一篇關於session的好文章,寫的很詳細
    • Apache2.2 + SSL 配置
    • JAVA日期時間顯示
    • JAVA計時器
    • MD5 Java Script 版 原始碼

    動態訂閱

    文章精選

    文章搜尋

    誰來我家

    參觀人氣

    • 本日人氣:
    • 累積人氣: