Vincent Jia 博客

          to be a better man, to be a bad man.

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            29 隨筆 :: 3 文章 :: 0 評論 :: 0 Trackbacks

          #

          具體來說cookie機制采用的是在客戶端保持狀態的方案,而session機制采用的是在服務器端保持狀態的方案。同時我們也看到,由于采用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助于cookie機制來達到保存標識的目的,但實際上它還有其他選擇。

              cookie機制。正統的cookie分發是通過擴展HTTP協議來實現的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由瀏覽器按照一定的原則在后臺自動發送給服務器的。瀏覽器檢查所有存儲的cookie,如果某個cookie所聲明的作用范圍大于等于將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發送給服務器
              cookie的內容主要包括:名字,值,過期時間,路徑和域。路徑與域一起構成cookie的作用范圍若不設置過期時間,則表示這個cookie的生命期為瀏覽器會話期間,關閉瀏覽器窗口,cookie就消失。這種生命期為瀏覽器會話期的cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內存里,當然這種行為并不是規范規定的。若設置了過期時間,瀏覽器就會把cookie保存到硬盤上,關閉后再次打開瀏覽器,這些cookie仍然有效直到超過設定的過期時間。存儲在硬盤上的cookie可以在不同的瀏覽器進程間共享,比如兩個IE窗口。而對于保存在內存里的cookie,不同的瀏覽器有不同的處理方式
              session機制。session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。
           
              當程序需要為某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端創建過session,服務器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session并且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。
              保存這個session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發揮給服務器。一般這個cookie的名字都是類似于SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器。
              經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的后面。還有一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把session id傳遞回服務器。比如:
               <form name="testform" action="/xxx">
               <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
               <input type="text">
               </form>
          實際上這種技術可以簡單的用對action應用URL重寫來代替。
          posted @ 2010-06-02 15:03 iLinux 閱讀(153) | 評論 (0)編輯 收藏

          第一部分 DWR是什么,如何使用

              DWR是一個開源的類庫,可以幫助開發人員開發包含AJAX技術的網站.它可以允許在瀏覽器里的代碼(javascript)使用運行在WEB服務器上的 JAVA函數,就像它就在瀏覽器里一樣. 它包含兩個主要的部分:允許JavaScript從WEB服務器上一個遵循了AJAX原則的Servlet(小應用程序)中獲取數據.另外一方面一個 JavaScript庫可以幫助網站開發人員輕松地利用獲取的數據來動態改變網頁的內容.
              官方網站地址http://getahead.org/dwr

          關于DWR的使用 引用別人的文章。   

          開始使用 DWR
              原文出處: http://www.javatang.com/archives/2006/10/20/254879.html
              翻譯: Jet Mah
              有兩種方法來開始 DWR 的學習,最簡單的做法是下載官方提供的 WAR 文件然后對此深入研究。不過這種方式不能使你感到將 DWR 整合到你現有的 web 程序有多么的簡單,所以我們推薦你跟隨下面三個步驟:

          1. 安裝 DWR JAR 包
          下載 dwr.jar 文件,然后將它放在 web 程序的 WEB-INF/lib 目錄下面,很可能在這個目錄下已經有一些 jar 文件了。

          2. 編輯 config 文件

          將下面的代碼添加到 WEB-INF/web.xml 文件中,<servlet>需要放在另外的<servlet>之后,<servlet-mapping>也是如此。

          <servlet>
             <servlet-name>dwr-invoker</servlet-name>
             <display-name>DWR Servlet</display-name>
             <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
             <init-param>
                <param-name>debug</param-name>
                <param-value>true</param-value>
             </init-param>
          </servlet>

          <servlet-mapping>
             <servlet-name>dwr-invoker</servlet-name>
             <url-pattern>/dwr/*</url-pattern>
          </servlet-mapping>

          接下來創建 dwr.xml 文件并將此放在 web.xml 所在的 WEB-INF 目錄下。文件中類似下面的內容:

          <!DOCTYPE dwr PUBLIC
               ”-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN”
               ”http://www.getahead.ltd.uk/dwr/dwr10.dtd”>

          <dwr>
             <allow>
               <create creator=”new” javascript=”JDate”>
                 <param name=”class” value=”java.util.Date”/>
               </create>
               <create creator=”new” javascript=”Demo”>
                 <param name=”class” value=”your.java.Bean”/>
               </create>
             </allow>
          </dwr>

          DWR 配置文件定義了由 DWR 創建和被 Javascript 遠程使用的類。在上面的例子中我們在遠程創建了2個類,并且給出了在 Javascript 中的類名。

          上面使用的 new creator 使用了所有的 JavaBeans 必須含有的公有(public)無參(no-args)的構造函數。值得一提的是, DWR 還有一些限制:

        1. 避免使用 JavaScript 保留字;以保留字命名的方法將自動被排除。大多數 JavaScript 的保留字同時也是 Java 的保留字,因此無論如何你也不能使用一個名為 “try()” 的方法。但是最常用的一個詞 “delete()”,在 JavaScript 中有特殊的含義而在 Java 中沒有。
        2. 重載方法(Overloaded methods)將會在調用的時候陷入未知的狀況,因此應該避免重載方法。

          3. 訪問下面的地址
          http://localhost:8080/[YOUR-WEBAPP]/dwr/

          你應該會看到一個頁面,上面顯示了剛才你在第二步所創建的類。進入一個鏈接之后你會看到所有等待調用方法的列表。這些動態產生的例子你也能通過 DWR 來實現。

          親自嘗試和體會下吧。

          怎樣應用到你的 Web 程序中?

          在側邊欄有很多例子演示了怎樣改變網頁中的文本、更新列表、操作表單和動態修改表格。每一個例子都有詳細的說明。

          另外一個開始方法就是從頁面中查看源代碼,這些頁面你剛剛瀏覽過:

        3. 進入 http://localhost:8080/[YOUR-WEBAPP]/dwr/ 然后點擊你創建的類;
        4. 查看源代碼然后定位到你所感興趣的方法的代碼行;
        5. 將這些文本粘貼到你 Web 程序的一個 HTML 或 JSP頁面中;
        6. 包含下面的 javascrip 文件:

          <script src=’/[YOUR-WEBAPP]/dwr/interface/[YOUR-SCRIPT].js’></script>
          <script src=’/[YOUR-WEBAPP]/dwr/engine.js’></script>

          你可以根據實際情況修改 /[YOUR-WEBAPP]/ 部分。

          關于怎樣書寫 DWR 控制的 Javascript 代碼請查看 腳本簡介。

        7. posted @ 2010-06-02 14:40 iLinux 閱讀(145) | 評論 (0)編輯 收藏

               摘要:   閱讀全文
          posted @ 2010-03-29 16:13 iLinux 閱讀(4856) | 評論 (0)編輯 收藏

          是不是應該進入有可能實施互聯網、廣電系統、電信領域的某一方呢?
          機遇的聲音喊得很響亮,金三銀四的日子,想動一動了

          posted @ 2010-03-15 14:13 iLinux 閱讀(79) | 評論 (0)編輯 收藏

          簡單討論JVM的class加載機制,給出兩個反射的例子代碼并分析工作原理,并給出了sun的動態代理實現原理——代碼生成

          JavaVM,反射與動態代理

           

          Java程序的工作機制:Java對象都以單獨的class文件存在,java虛擬機將其載入并執行其虛擬機指令。

           

          Java虛擬機查找這些java對象:

          java虛擬機根據class path來查找java對象,而虛擬機的class path又分為三層:

          bootstrapsun.boot.class.path

          extension: java.ext.dirs

          application: java.class.path

          三個class path各有對應的classloader。由上而下形成父子關系

          當程序中調用new指令,或者ClassLoader.load方法時。其順序如下:

          1.       首先查看applicationclassloader中是否已有對應的class緩存,如果有則返回,并根據class分配內存。如果沒有,接下一步。

          2.       首先查看extensionclassloader中是否已有對應的class緩存,如果有則返回,并根據class分配內存。如果沒有,接下一步。

          3.       首先查看bootstrapclassloader中是否已有對應的class緩存,如果有則返回,并根據class分配內存。如果沒有,接下一步。

          4.       bootstrapclassloader在其class path中試圖加載該class,如果有,則將該class放入cache中,并返回。如果沒有,接下一步。

          5.       extensionclassloader在其class path中試圖加載該class,如果有,則將該class放入cache中,并返回。如果沒有,接下一步。

          6.       applicationclassloader在其class path中試圖加載該class,如果有,則將該class放入cache中,并返回。如果沒有,則拋出ClassNotFoundexception。

           

          Java虛擬機加載這些java對象:

          每個java虛擬機都在其啟動時產生一個唯一的class heap,并把所有的class instance都分配在其中。其中每個類實例的信息又分兩部分,fields域和methods域。每個類實例各自擁有fields,但同一個類的不同實例共享methods

           

          反射

          JVM對反射的處理

          簡單例子代碼:

          import java.lang.reflect.InvocationHandler;

          import java.lang.reflect.Method;

          import java.lang.reflect.InvocationTargetException;

          import java.io.IOException;

           

          public class Main {

              public static void main(String[] args){

                  TempImpl t1 = new TempImpl("temp1");

                  try {

                      Method t1Talk = t1.getClass().getMethod("Talk", new Class[0]) ;

                      t1Talk.invoke(t1, null);

                  } catch (NoSuchMethodException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  } catch (IllegalAccessException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  } catch (InvocationTargetException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  }

                  try {

                      System.in.read();

                  } catch (IOException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  }

              }

          }

          復雜例子代碼:

          import java.lang.reflect.InvocationHandler;

          import java.lang.reflect.Method;

          import java.lang.reflect.InvocationTargetException;

          import java.io.IOException;

           

          public class Main {

              public static void main(String[] args){

                  TempImpl t1 = new TempImpl("temp1");

                  TempImpl t2 = new TempImpl("temp2");

                  Temp2 temp2 = new Temp2();

                  try {

                      Method t1Talk = t1.getClass().getMethod("Talk", new Class[0]) ;

                      Method t2Talk = t2.getClass().getMethod("Talk", new Class[0]) ;

                      t1Talk.invoke(t2, null);

                      t2Talk.invoke(t1, null);

                      if(t1Talk.equals(t2Talk)){

                          System.out.println("equals");

                      }

                     else{

                          System.out.println("not equals");

                      }

                      if(t1Talk==t2Talk){

                          System.out.println("ref equals");

                      }

                     else{

                          System.out.println("ref not equals");

                      }

                      t2Talk.invoke(temp2, null);

                  } catch (NoSuchMethodException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  } catch (IllegalAccessException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  } catch (InvocationTargetException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  }

                  try {

                      System.in.read();

                  } catch (IOException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  }

              }

          }

           

          分析:java虛擬機把每個methods當作一個執行單元。該執行單元帶有兩種簽名:類簽名和屬性簽名(publicstatic等)。 反射的第一步,驗證簽名的合法性。驗證通過后,順序執行該method中的指令,當需要訪問類實例的fields和傳入參數時,由虛擬機注入。

           

          動態代理

          Sun對動態代理的說明:

          一個簡單例子代碼:

          動態代理的內部實現——代碼生成:

          研究JDK源代碼,發現在Proxysun實現中調用了sun.misc.ProxyGenerator類的generateProxyClass( proxyName, interfaces)方法,其返回值為byte[]class文件的內存類型一致。于是做如下試驗:

          public class ProxyClassFile{

                 public static void main(String[] args){

                        String proxyName = "TempProxy";

                  TempImpl t = new TempImpl("proxy");

                        Class[] interfaces =t.getClass().getInterfaces();

                       

                        byte[] proxyClassFile = ProxyGenerator.generateProxyClass(

                            proxyName, interfaces);

                  File f = new File("classes/TempProxy.class");

                  try {

                      FileOutputStream fos = new FileOutputStream(f);

                      fos.write(proxyClassFile);

                      fos.flush();

                      fos.close();

                  } catch (FileNotFoundException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  } catch (IOException e) {

                      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

                  }

                 }

          }

          運行該類,到class文件夾下,利用反編譯技術,發現原來其采用了代碼生產技術:

           

          public interface Temp{

                 public void Talk();

                 public void Run();

          }

          import java.lang.reflect.*;

           

          public final class TempProxy extends Proxy

              implements Temp{

           

              private static Method m4;

              private static Method m2;

              private static Method m0;

              private static Method m3;

              private static Method m1;

           

              public TempProxy(InvocationHandler invocationhandler)   {

                  super(invocationhandler);

              }

           

              public final void Run()    {

                  try {

                      h.invoke(this, m4, null);

                      return;

                  }

                  catch(Error _ex) { }

                  catch(Throwable throwable) {

                      throw new UndeclaredThrowableException(throwable);

                  }

              }

           

              public final String toString(){

                  try{

                      return (String)h.invoke(this, m2, null);

                  }

                  catch(Error _ex) { }

                  catch(Throwable throwable)  {

                      throw new UndeclaredThrowableException(throwable);

                  }

                  return "";

              }

           

              public final int hashCode() {

                  try {

                      return ((Integer)h.invoke(this, m0, null)).intValue();

                  }

                  catch(Error _ex) { }

                  catch(Throwable throwable){

                      throw new UndeclaredThrowableException(throwable);

                  }

                  return 123;

              }

           

              public final void Talk(){

                  try{

                      h.invoke(this, m3, null);

                      return;

                  }

                  catch(Error _ex) { }

                  catch(Throwable throwable) {

                      throw new UndeclaredThrowableException(throwable);

                  }

              }

           

              public final boolean equals(Object obj) {

                  try {

                      return ((Boolean)h.invoke(this, m1, new Object[] {

                          obj

                      })).booleanValue();

                  }

                  catch(Error _ex) { }

                  catch(Throwable throwable) {

                      throw new UndeclaredThrowableException(throwable);

                  }

                  return false;

              }

           

              static{

                  try{

               m4 = Class.forName("Temp").getMethod("Run", new Class[0]);

               m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);

               m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);

               m3 = Class.forName("Temp").getMethod("Talk", new Class[0]);

               m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {

                          Class.forName("java.lang.Object")

                      });

                  }

                  catch(NoSuchMethodException nosuchmethodexception) {

                     throw new NoSuchMethodError(nosuchmethodexception.getMessage());

                  }

                  catch(ClassNotFoundException classnotfoundexception) {

                      throw new NoClassDefFoundError(classnotfoundexception.getMessage());

                  }

              }

          }

           from: http://www.cnblogs.com/fengye/archive/2007/02/18/652389.html

          posted @ 2010-02-10 14:00 iLinux 閱讀(165) | 評論 (0)編輯 收藏

          僅列出標題
          共3頁: 上一頁 1 2 3 
          主站蜘蛛池模板: 新晃| 贵德县| 利津县| 大同县| 巴彦县| 巴林右旗| 屯门区| 河源市| 尖扎县| 宁城县| 从化市| 图木舒克市| 汶上县| 渝北区| 昌平区| 红安县| 米林县| 安龙县| 敦化市| 嘉兴市| 镇坪县| 鹤峰县| 苍梧县| 肥西县| 敦化市| 洱源县| 遵义县| 沂水县| 休宁县| 乡城县| 南通市| 贵德县| 莲花县| 奇台县| 东山县| 潞西市| 金平| 泰州市| 镇平县| 内江市| 威宁|