Look into it ~

          present
          隨筆 - 32, 文章 - 0, 評(píng)論 - 3, 引用 - 0
          數(shù)據(jù)加載中……

          2008年8月20日

          android軟件

              只有注冊(cè)用戶登錄后才能閱讀該文。閱讀全文

          posted @ 2008-11-20 16:24 LukeW 閱讀(36) | 評(píng)論 (0)編輯 收藏

          linux設(shè)備模型

          Linux 2.6內(nèi)核的一個(gè)重要特色是提供了統(tǒng)一的內(nèi)核設(shè)備模型。隨著技術(shù)的不斷進(jìn)步,系統(tǒng)的拓?fù)浣Y(jié)構(gòu)越來越復(fù)雜,對(duì)智能電源管理、熱插拔以及plug and play的支持要求也越來越高,2.4內(nèi)核已經(jīng)難以滿足這些需求。為適應(yīng)這種形勢(shì)的需要,2.6內(nèi)核開發(fā)了全新的設(shè)備模型。
          1. Sysfs文件系統(tǒng)
          Sysfs文件系統(tǒng)是一個(gè)類似于proc文件系統(tǒng)的特殊文件系統(tǒng),用于將系統(tǒng)中的設(shè)備組織成層次結(jié)構(gòu),并向用戶模式程序提供詳細(xì)的內(nèi)核數(shù)據(jù)結(jié)構(gòu)信息。其頂層目錄主要有:
          Block目錄:包含所有的塊設(shè)備
          Devices目錄:包含系統(tǒng)所有的設(shè)備,并根據(jù)設(shè)備掛接的總線類型組織成層次結(jié)構(gòu)
          Bus目錄:包含系統(tǒng)中所有的總線類型
          Drivers目錄:包括內(nèi)核中所有已注冊(cè)的設(shè)備驅(qū)動(dòng)程序
          Class目錄:系統(tǒng)中的設(shè)備類型(如網(wǎng)卡設(shè)備,聲卡設(shè)備等)
          2. 內(nèi)核對(duì)象機(jī)制關(guān)鍵數(shù)據(jù)結(jié)構(gòu)
          2.1 kobject內(nèi)核對(duì)象
          Kobject 是Linux 2.6引入的新的設(shè)備管理機(jī)制,在內(nèi)核中由struct kobject表示。通過這個(gè)數(shù)據(jù)結(jié)構(gòu)使所有設(shè)備在底層都具有統(tǒng)一的接口,kobject提供基本的對(duì)象管理,是構(gòu)成Linux 2.6設(shè)備模型的核心結(jié)構(gòu),它與sysfs文件系統(tǒng)緊密關(guān)聯(lián),每個(gè)在內(nèi)核中注冊(cè)的kobject對(duì)象都對(duì)應(yīng)于sysfs文件系統(tǒng)中的一個(gè)目錄。
          Kobject結(jié)構(gòu)定義為:
          struct kobject {
          char * k_name;    // 指向設(shè)備名稱的指針
          char name[KOBJ_NAME_LEN];   // 設(shè)備名稱
          struct kref kref;    // 對(duì)象引用計(jì)數(shù)
          struct list_head entry;   // 掛接到所在kset中去的單元
          struct kobject * parent; // 指向父對(duì)象的指針
          struct kset * kset;    // 所屬kset的指針
          struct kobj_type * ktype;   // 指向其對(duì)象類型描述符的指針
          struct dentry * dentry; // sysfs文件系統(tǒng)中與該對(duì)象對(duì)應(yīng)的文件節(jié)點(diǎn)路徑指針
          };

          其中的kref域表示該對(duì)象引用的計(jì)數(shù),內(nèi)核通過kref實(shí)現(xiàn)對(duì)象引用計(jì)數(shù)管理,內(nèi)核提供兩個(gè)函數(shù)kobject_get()、kobject_put()分別用于增加和減少引用計(jì)數(shù),當(dāng)引用計(jì)數(shù)為0時(shí),所有該對(duì)象使用的資源將被釋放。
          Ktype 域是一個(gè)指向kobj_type結(jié)構(gòu)的指針,表示該對(duì)象的類型。Kobj_type數(shù)據(jù)結(jié)構(gòu)包含三個(gè)域:一個(gè)release方法用于釋放kobject占 用的資源;一個(gè)sysfs_ops指針指向sysfs操作表和一個(gè)sysfs文件系統(tǒng)缺省屬性列表。Sysfs操作表包括兩個(gè)函數(shù)store()和 show()。當(dāng)用戶態(tài)讀取屬性時(shí),show()函數(shù)被調(diào)用,該函數(shù)編碼指定屬性值存入buffer中返回給用戶態(tài);而store()函數(shù)用于存儲(chǔ)用戶態(tài) 傳入的屬性值。
          2.2 kset內(nèi)核對(duì)象集合
          Kobject通常通過kset組織成層次化的結(jié)構(gòu),kset是具有相同類型的kobject的集合,在內(nèi)核中用kset數(shù)據(jù)結(jié)構(gòu)表示,定義為:
          struct kset {
          struct subsystem * subsys;   // 所在的subsystem的指針
          struct kobj_type * ktype;   // 指向該kset對(duì)象類型描述符的指針
          struct list_head list;      // 用于連接該kset中所有kobject的鏈表頭
          struct kobject kobj;    // 嵌入的kobject
          struct kset_hotplug_ops * hotplug_ops; // 指向熱插拔操作表的指針
          };

          包 含在kset中的所有kobject被組織成一個(gè)雙向循環(huán)鏈表,list域正是該鏈表的頭。Ktype域指向一個(gè)kobj_type結(jié)構(gòu),被該 kset中的所有kobject共享,表示這些對(duì)象的類型。Kset數(shù)據(jù)結(jié)構(gòu)還內(nèi)嵌了一個(gè)kobject對(duì)象(由kobj域表示),所有屬于這個(gè)kset 的kobject對(duì)象的parent域均指向這個(gè)內(nèi)嵌的對(duì)象。此外,kset還依賴于kobj維護(hù)引用計(jì)數(shù):kset的引用計(jì)數(shù)實(shí)際上就是內(nèi)嵌的 kobject對(duì)象的引用計(jì)數(shù)。
          2.3 subsystem內(nèi)核對(duì)象子系統(tǒng)
          Subsystem是一系列kset的集合,描述系統(tǒng)中某一 類設(shè)備子系統(tǒng),如block_subsys表示所有的塊設(shè)備,對(duì)應(yīng)于sysfs文件系統(tǒng)中的block目錄。類似的,devices_subsys對(duì)應(yīng)于 sysfs中的devices目錄,描述系統(tǒng)中所有的設(shè)備。Subsystem由struct subsystem數(shù)據(jù)結(jié)構(gòu)描述,定義為:
          struct subsystem {
          struct kset kset;       // 內(nèi)嵌的kset對(duì)象
          struct rw_semaphore rwsem; // 互斥訪問信號(hào)量
          };

          每 個(gè)kset必須屬于某個(gè)subsystem,通過設(shè)置kset結(jié)構(gòu)中的subsys域指向指定的subsystem可以將一個(gè)kset加入到該 subsystem。所有掛接到同一subsystem的kset共享同一個(gè)rwsem信號(hào)量,用于同步訪問kset中的鏈表。

          3. 內(nèi)核對(duì)象機(jī)制主要相關(guān)函數(shù)
          針對(duì)內(nèi)核對(duì)象不同層次的數(shù)據(jù)結(jié)構(gòu),linux 2.6內(nèi)核定義了一系列操作函數(shù),定義于lib/kobject.c文件中。
          3.1 kobject相關(guān)函數(shù)
          void kobject_init(struct kobject * kobj);// kobject初始化函數(shù)。設(shè)置kobject引用計(jì)數(shù)為1,entry域指向自身,其所屬kset引用計(jì)數(shù)加1

          int kobject_set_name(struct kobject *kobj, const char *format, );// 設(shè)置指定kobject的名稱。

          void kobject_cleanup(struct kobject * kobj);
          void kobject_release(struct kref *kref);// kobject清除函數(shù)。當(dāng)其引用計(jì)數(shù)為0時(shí),釋放對(duì)象占用的資源。

          struct kobject *kobject_get(struct kobject *kobj);// 將kobj 對(duì)象的引用計(jì)數(shù)加1,同時(shí)返回該對(duì)象的指針。

          void kobject_put(struct kobject * kobj);// 將kobj對(duì)象的引用計(jì)數(shù)減1,如果引用計(jì)數(shù)降為0,則調(diào)用kobject_release()釋放該kobject對(duì)象。

          int kobject_add(struct kobject * kobj);// 將kobj對(duì)象加入Linux設(shè)備層次。掛接該kobject對(duì)象到kset的list鏈中,增加父目錄各級(jí)kobject的引用計(jì)數(shù),在其parent指向的目錄下創(chuàng)建文件節(jié)點(diǎn),并啟動(dòng)該類型內(nèi)核對(duì)象的hotplug函數(shù)。

          int kobject_register(struct kobject * kobj);// kobject注冊(cè)函數(shù)。通過調(diào)用kobject_init()初始化kobj,再調(diào)用kobject_add()完成該內(nèi)核對(duì)象的注冊(cè)。

          void kobject_del(struct kobject * kobj);// 從Linux設(shè)備層次(hierarchy)中刪除kobj對(duì)象。

          void kobject_unregister(struct kobject * kobj);// kobject注銷函數(shù)。與kobject_register()相反,它首先調(diào)用kobject_del從設(shè)備層次中刪除該對(duì)象,再調(diào)用kobject_put()減少該對(duì)象的引用計(jì)數(shù),如果引用計(jì)數(shù)降為0,則釋放該kobject對(duì)象。

          3.2 kset相關(guān)函數(shù)
          與kobject 相似,kset_init()完成指定kset的初始化,kset_get()和kset_put()分別增加和減少kset對(duì)象的引用計(jì)數(shù)。 Kset_add()和kset_del()函數(shù)分別實(shí)現(xiàn)將指定keset對(duì)象加入設(shè)備層次和從其中刪除;kset_register()函數(shù)完成 kset的注冊(cè)而kset_unregister()函數(shù)則完成kset的注銷。
          3.3 subsystem相關(guān)函數(shù)
          subsystem有一組完成類似的函數(shù),分別是:
          void subsystem_init(struct subsystem *subsys);
          int subsystem_register(struct subsystem *subsys);
          void subsystem_unregister(struct subsystem *subsys);
          struct subsystem *subsys_get(struct subsystem *subsys)
          void subsys_put(struct subsystem *subsys);

          4. 設(shè)備模型組件
          在上述內(nèi)核對(duì)象機(jī)制的基礎(chǔ)上,Linux的設(shè)備模型建立在幾個(gè)關(guān)鍵組件的基礎(chǔ)上,下面我們?cè)敿?xì)闡述這些組件。
          4.1 devices
          系統(tǒng)中的任一設(shè)備在設(shè)備模型中都由一個(gè)device對(duì)象描述,其對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)struct device定義為:
          struct device {
          struct list_head g_list;
          struct list_head node;
              
          struct list_head bus_list;
              
          struct list_head driver_list;
              
          struct list_head children;
              
          struct device *parent;
              
          struct kobject kobj;
              
          char bus_id[BUS_ID_SIZE];
              
          struct bus_type *bus;
              
          struct device_driver *driver;
              
          void *driver_data;
              
          /* Several fields omitted */
          };

          g_list 將該device對(duì)象掛接到全局設(shè)備鏈表中,所有的device對(duì)象都包含在devices_subsys中,并組織成層次結(jié)構(gòu)。Node域?qū)⒃搶?duì)象掛接 到其兄弟對(duì)象的鏈表中,而bus_list則用于將連接到相同總線上的設(shè)備組織成鏈表,driver_list則將同一驅(qū)動(dòng)程序管理的所有設(shè)備組織為鏈 表。此外,children域指向該device對(duì)象子對(duì)象鏈表頭,parent域則指向父對(duì)象。Device對(duì)象還內(nèi)嵌一個(gè)kobject對(duì)象,用于引 用計(jì)數(shù)管理并通過它實(shí)現(xiàn)設(shè)備層次結(jié)構(gòu)。Driver域指向管理該設(shè)備的驅(qū)動(dòng)程序?qū)ο螅鴇river_data則是提供給驅(qū)動(dòng)程序的數(shù)據(jù)。Bus域描述設(shè) 備所連接的總線類型。
          內(nèi)核提供了相應(yīng)的函數(shù)用于操作device對(duì)象。其中Device_register()函數(shù)將一個(gè)新的device對(duì)象插 入設(shè)備模型,并自動(dòng)在/sys/devices下創(chuàng)建一個(gè)對(duì)應(yīng)的目錄。Device_unregister()完成相反的操作,注銷設(shè)備對(duì)象。 Get_device()和put_device()分別增加與減少設(shè)備對(duì)象的引用計(jì)數(shù)。通常device結(jié)構(gòu)不單獨(dú)使用,而是包含在更大的結(jié)構(gòu)中作為一 個(gè)子結(jié)構(gòu)使用,比如描述PCI設(shè)備的struct pci_dev,其中的dev域就是一個(gè)device對(duì)象。
          4.2 drivers
          系統(tǒng)中的每個(gè)驅(qū)動(dòng)程序由一個(gè)device_driver對(duì)象描述,對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)定義為:
          struct device_driver {
              
          char *name;   // 設(shè)備驅(qū)動(dòng)程序的名稱
              struct bus_type *bus; // 該驅(qū)動(dòng)所管理的設(shè)備掛接的總線類型
              struct kobject kobj;    // 內(nèi)嵌kobject對(duì)象
              struct list_head devices;  // 該驅(qū)動(dòng)所管理的設(shè)備鏈表頭
              int (*probe)(struct device *dev); // 指向設(shè)備探測(cè)函數(shù),用于探測(cè)設(shè)備是否可以被該驅(qū)動(dòng)程序管理
          int (*remove)(struct device *dev); // 用于刪除設(shè)備的函數(shù)
          /*
           some fields omitted*/
          };

          與device 結(jié)構(gòu)類似,device_driver對(duì)象依靠?jī)?nèi)嵌的kobject對(duì)象實(shí)現(xiàn)引用計(jì)數(shù)管理和層次結(jié)構(gòu)組織。內(nèi)核提供類似的函數(shù)用于操作 device_driver對(duì)象,如get_driver()增加引用計(jì)數(shù),driver_register()用于向設(shè)備模型插入新的driver對(duì) 象,同時(shí)在sysfs文件系統(tǒng)中創(chuàng)建對(duì)應(yīng)的目錄。Device_driver()結(jié)構(gòu)還包括幾個(gè)函數(shù),用于處理熱拔插、即插即用和電源管理事件。
          4.3   buses
          系統(tǒng)中總線由struct bus_type描述,定義為:
          struct bus_type {
          char   * name; // 總線類型的名稱
          struct subsystem subsys; // 與該總線相關(guān)的subsystem
          struct kset drivers; // 所有與該總線相關(guān)的驅(qū)動(dòng)程序集合
          struct kset devices; // 所有掛接在該總線上的設(shè)備集合
          struct bus_attribute * bus_attrs; // 總線屬性
          struct device_attribute * dev_attrs; // 設(shè)備屬性
          struct driver_attribute * drv_attrs;   // 驅(qū)動(dòng)程序?qū)傩?/span>
          int (*match)(struct device * dev, struct device_driver * drv);
          int (*hotplug) (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
          int (*suspend)(struct device * dev, u32 state);
          int (*resume)(struct device * dev);
          };

          每 個(gè)bus_type對(duì)象都內(nèi)嵌一個(gè)subsystem對(duì)象,bus_subsys對(duì)象管理系統(tǒng)中所有總線類型的subsystem對(duì)象。每個(gè) bus_type對(duì)象都對(duì)應(yīng)/sys/bus目錄下的一個(gè)子目錄,如PCI總線類型對(duì)應(yīng)于/sys/bus/pci。在每個(gè)這樣的目錄下都存在兩個(gè)子目 錄:devices和drivers(分別對(duì)應(yīng)于bus_type結(jié)構(gòu)中的devices和drivers域)。其中devices子目錄描述連接在該總 線上的所有設(shè)備,而drivers目錄則描述與該總線關(guān)聯(lián)的所有驅(qū)動(dòng)程序。與device_driver對(duì)象類似,bus_type結(jié)構(gòu)還包含幾個(gè)函數(shù) (match()、hotplug()等)處理相應(yīng)的熱插拔、即插即拔和電源管理事件。
          4.4 classes
          系統(tǒng)中的設(shè)備類由 struct class描述,表示某一類設(shè)備。所有的class對(duì)象都屬于class_subsys子系統(tǒng),對(duì)應(yīng)于sysfs文件系統(tǒng)中的/sys/class目錄。 每個(gè)class對(duì)象包括一個(gè)class_device鏈表,每個(gè)class_device對(duì)象表示一個(gè)邏輯設(shè)備,并通過struct class_device中的dev域(一個(gè)指向struct device的指針)關(guān)聯(lián)一個(gè)物理設(shè)備。這樣,一個(gè)邏輯設(shè)備總是對(duì)應(yīng)于一個(gè)物理設(shè)備,但是一個(gè)物理設(shè)備卻可能對(duì)應(yīng)于多個(gè)邏輯設(shè)備。此外,class結(jié)構(gòu)中 還包括用于處理熱插拔、即插即拔和電源管理事件的函數(shù),這與device對(duì)象和driver對(duì)象相似。

          posted @ 2008-11-12 23:14 LukeW 閱讀(190) | 評(píng)論 (0)編輯 收藏

          位運(yùn)算

          C中的位運(yùn)算
          能夠運(yùn)用到任何整形的數(shù)據(jù)類型上(包括char, int), 無論有沒有short, long, unsigned這樣的限定詞.


          位運(yùn)算的應(yīng)用
          // 交換指針變量x,y所指向的存儲(chǔ)位置處存放的值
          // 優(yōu)勢(shì)是不需要第三個(gè)位置來臨時(shí)存儲(chǔ)另一個(gè)值
          // 但是這個(gè)方法并沒有明顯的性能優(yōu)勢(shì),只是一個(gè)智力上的消遣
          void inplace_swap(int *x, int *y)
          {
           
          *= *^ *y;
           
          *= *^ *y;
           
          *= *^ *y;
          }

          位運(yùn)算常見用法:
          實(shí)現(xiàn)掩碼運(yùn)算



          -----------------------------------
          Java中的位運(yùn)算


          posted @ 2008-11-12 13:53 LukeW 閱讀(135) | 評(píng)論 (0)編輯 收藏

          大端小端 -- 各系統(tǒng)及機(jī)器的信息表示

          因?yàn)楝F(xiàn)行的計(jì)算機(jī)都是以八位一個(gè)字節(jié)為存儲(chǔ)單位,那么一個(gè)16位的整數(shù),也就是C語言中的short,在內(nèi)存中可能有兩種存儲(chǔ)順序big-

          endian和litte-endian.考慮一個(gè)short整數(shù)0x3132(0x32是低位,0x31是高位),把它賦值給一個(gè)short變量,那么它在內(nèi)存中的存儲(chǔ)可

          能有如下兩種情況:
          大端字節(jié)(Big-endian):

          short變量地址
                 0x1000                  0x1001
          ___________________________________
          |                 |
          |         0x31    |       0x32
          |________________ | ________________
          高位字節(jié)在低位字節(jié)的前面,也就是高位在內(nèi)存地址低的一端.可以這樣記住(大端->高位->在前->正常的邏輯順序)
           
          小端字節(jié)(little-endian):

          short變量地址
                 0x1000                  0x1001
          _____________________________________
          |                 |
          |         0x32    |       0x31
          |________________ | __________________
          低位字節(jié)在高位字節(jié)的前面,也就是低位在內(nèi)存地址低的一端.可以這樣記住(小端->低位->在前->與正常邏輯順序相反)
           
          可以做個(gè)實(shí)驗(yàn)
          在windows上下如下程序
          #include <stdio.h>
          #include 
          <assert.h>
           
          void main( void )
          {
                  
          short test;
                  FILE
          * fp;
                  
                  test 
          = 0x3132;  //(31ASIIC碼的’1’,32ASIIC碼的’2’)
                  if ((fp = fopen ("c:""test.txt""wb")) == NULL)
                        assert(
          0);
                  fwrite(
          &test, sizeof(short), 1, fp);
                  fclose(fp);
          }

              然后在C盤下打開test.txt文件,可以看見內(nèi)容是21,而test等于0x3132,可以明顯的看出來x86的字節(jié)順序是低位在前.如果我們
          把這段同樣的代碼放到(big-endian)的機(jī)器上執(zhí)行,那么打出來的文件就是12.這在本機(jī)中使用是沒有問題的.但當(dāng)你把這個(gè)文件從一
          個(gè)big- endian機(jī)器復(fù)制到一個(gè)little-endian機(jī)器上時(shí)就出現(xiàn)問題了.

              如上述例子,我們?cè)赽ig-endian的機(jī)器上創(chuàng)建了這個(gè)test文件,把其復(fù)制到little-endian的機(jī)器上再用fread讀到一個(gè) short里
          面,我們得到的就不再是0x3132而是0x3231了,這樣讀到的數(shù)據(jù)就是錯(cuò)誤的,所以在兩個(gè)字節(jié)順序不一樣的機(jī)器上傳輸數(shù)據(jù)時(shí)需要特別
          小心字節(jié)順序,理解了字節(jié)順序在可以幫助我們寫出移植行更高的代碼.

          正因?yàn)橛凶止?jié)順序的差別,所以在網(wǎng)絡(luò)傳輸?shù)臅r(shí)候定義了所有字節(jié)順序相關(guān)的數(shù)據(jù)都使用big-endian,BSD的代碼中定義了四個(gè)宏來處
          理:
          #define ntohs(n)     //網(wǎng)絡(luò)字節(jié)順序到主機(jī)字節(jié)順序 n代表net, h代表host, s代表short
          #define htons(n)     //主機(jī)字節(jié)順序到網(wǎng)絡(luò)字節(jié)順序 n代表net, h代表host, s代表short
          #define ntohl(n)      //網(wǎng)絡(luò)字節(jié)順序到主機(jī)字節(jié)順序 n代表net, h代表host, s代表 long
          #define htonl(n)      //主機(jī)字節(jié)順序到網(wǎng)絡(luò)字節(jié)順序 n代表net, h代表host, s代表 long

          舉例說明下這其中一個(gè)宏的實(shí)現(xiàn):
           #define sw16(x) "
              ((
          short)( "
                  (((short)(x) & (short)0x00ffU<< 8| "
                  (((short)(x) & (short)0xff00U>> 8) ))

          這里實(shí)現(xiàn)的是一個(gè)交換兩個(gè)字節(jié)順序.其他幾個(gè)宏類似.

          我們改寫一下上面的程序
          #include <stdio.h>
          #include 
          <assert.h>

          #define sw16(x) "
              ((
          short)( "
                  (((short)(x) & (short)0x00ffU<< 8| "
                  (((short)(x) & (short)0xff00U>> 8) ))

          // 因?yàn)閤86下面是低位在前,需要交換一下變成網(wǎng)絡(luò)字節(jié)順序
          #define htons(x) sw16(x)
           
          void main( void )
          {
                  
          short test;
                  FILE
          * fp;
                  
                  test 
          = htons(0x3132); //(31ASIIC碼的’1’,32ASIIC碼的’2’)
                  if ((fp = fopen ("c:""test.txt""wb")) == NULL)
                        assert(
          0);
                  fwrite(
          &test, sizeof(short), 1, fp);
                  fclose(fp);
          }

           
              如果在高字節(jié)在前的機(jī)器上,由于與網(wǎng)絡(luò)字節(jié)順序一致,所以我們什么都不干就可以了,只需要把#define htons(x) sw16(x)宏替

          換為 #define htons(x) (x).
              一開始我在理解這個(gè)問題時(shí),總在想為什么其他數(shù)據(jù)不用交換字節(jié)順序?比如說我們write一塊buffer到文件,最后終于想明白了,

          因?yàn)槎际莡nsigned char類型一個(gè)字節(jié)一個(gè)字節(jié)的寫進(jìn)去,這個(gè)順序是固定的,不存在字節(jié)順序的問題.

          【用函數(shù)判斷系統(tǒng)是Big Endian還是Little Endian】


          bool IsBig_Endian()
          //如果字節(jié)序?yàn)閎ig-endian,返回true;
          //反之為   little-endian,返回false
          {
              unsigned 
          short test = 0x1122;
              
          if(*( (unsigned char*&test ) == 0x11)
                 
          return TRUE;
          else
              
          return FALSE;

          }
          //IsBig_Endian()

          【打印程序?qū)ο蟮淖止?jié)表示】
          // 可在不同平臺(tái)與硬件架構(gòu)的機(jī)器中測(cè)試運(yùn)行這段代碼,理解大端表示和小端表示的不同.
          // 這段代碼使用強(qiáng)制類型轉(zhuǎn)換規(guī)避類型系統(tǒng)
          #incluede <stdio.h>

          // 假設(shè)每個(gè)字節(jié)都是非負(fù)整數(shù)
          typedef unsigned char *byte_pointer;

          void show_bytes(byte_pointer start, int len)
          {
           
          for(int i = 0; i < len; i++)
            printf(
          " %.2x", start[i]);
           printf(
          "\n");
          }

          void show_int(int x)
          {
           show_bytes((byte_pointer) 
          &x, sizeof(int));
          }

          void show_float(float x)
          {
           show_bytes((byte_pointer) 
          &x, sizeof(float));
          }

          // 在使用相同編碼(如ASCII編碼)的系統(tǒng)中,字符串字節(jié)表示得到的結(jié)果一般是相同的.所以文本數(shù)據(jù)比二進(jìn)制數(shù)據(jù)具有更強(qiáng)的平臺(tái)無關(guān)性
          void show_string(char *x)
          {
           show_bytes((byte_pointer) x, strlen(x));
          }

          void show_pointer(void *x)
          {
           show_bytes((byte_pointer) 
          &x, sizeof(void *));
          }

          void test_show_bytes(int val)
          {
           
          int ival = val;
           
          float fval = (float)ival;
           
          int *pval = &ival;
           
           show_int(ival); 
          // 各個(gè)機(jī)器因?yàn)榇蠖吮硎竞托《吮硎镜牟煌?從而只是字節(jié)順序不同
           show_float(fval); // 各個(gè)機(jī)器因?yàn)榇蠖吮硎竞托《吮硎镜牟煌?從而只是字節(jié)順序不同
           show_pointer(pval); // 指針值是與機(jī)器相關(guān)的(linux,sun使用4字節(jié)地址, 而alpha使用八字節(jié)地址)
          }

          ---------------------------------------------
          對(duì)于如數(shù)值12345在int型和float型時(shí)的編碼表示

          posted @ 2008-11-12 11:58 LukeW 閱讀(659) | 評(píng)論 (0)編輯 收藏

          點(diǎn)子

              只有注冊(cè)用戶登錄后才能閱讀該文。閱讀全文

          posted @ 2008-11-06 18:17 LukeW 閱讀(44) | 評(píng)論 (0)編輯 收藏

          j2me 聯(lián)網(wǎng)技術(shù)分析總結(jié)

          基本點(diǎn):

          Generic Connections

          In the CLDC Generic Connection framework, all connections are created using the open static method from the Connector class. If successful, this method returns an object that implements one of the generic connection interfaces. Figure 1 shows how these interfaces form an is-a hierarchy. The Connection interface is the base interface such that StreamConnectionNotifier is a Connection and InputConnection is a Connection too.

          fig1.gif
          Figure 1: Connection interface hierarchy
          • The Connection interface is the most basic connection type. It can only be opened and closed.
          • The InputConnection interface represents a device from which data can be read. Its openInputStream method returns an input stream for the connection.
          • The OuputConnection interface represents a device to which data can be written. Its openOutputStream method returns an output stream for the connection.
          • The StreamConnection interface combines the input and output connections.
          • The ContentConnection is a subinterface of StreamConnection. It provides access to some of the basic meta data information provided by HTTP connections.
          • The StreamConnectionNotified waits for a connection to be established. It returns a StreamConnection on which a communication link has ben established.
          • The DatagramConnection represents a datagram endpoint.

          The open method of the Connector class has the following syntax, where the String parameter has the format "protocol:address;parameters".

          Connector.open(String);

          Here are a few examples:

          HTTP Connection

          Connector.open("http://java.sun.com/developer");

          Datagram Connection

          Connector.open("datagram://address:port#");

          Communicate with a Port

          Connector.open("comm:0;baudrate=9600');

          Open Files

          Connector.open("file:/myFile.txt");


          The HttpConnection Interface:

          The HTTP protocol is a request-response application protocol in which the parameters of the request must be set before the request is sent. The connection could be in one of the three following states:
          • Setup: No connection yet
          • Connected: Connection has been made, the request has been sent, and some response is expected
          • Closed: Connection is closed

          In the setup state the following methods can be invoked:

          • setRequestMethod
          • setRequestProperty

          For example, suppose you have this connection:

          HttpConnection c = (HttpConnection)
          Connector.open(
          "http://java.sun.com/developer");

          Then, you can set the request method to be of type POST as follows:

          c.setRequestMethod(HttpConnection.POST);

          And likewise, you can set some of the HTTP properties. For example, you can set the User-Agent as follows:

          c.setRequestProperty("User-Agent","Profile/MIDP-1.0 Configuration/CLDC-1.0");

          If there is a method that requires data to be sent or received from the server, there is a state transition from Setup to Connected. Examples of methods that cause the transition include:

          openInputStream
          openOutputStream
          openDataInputStream
          openDataOutputStream
          getLength
          getType
          getDate
          getExpiration

          And while the connection is open, some of these methods that may be invoked:

          getURL
          getProtocol
          getHost
          getPort


          ------------------------------------------------------------
          要注意的問題:
          開發(fā)中遇到個(gè)很頭疼的問題, 與服務(wù)器通信write()數(shù)據(jù)時(shí)報(bào)java.io.IOException: Couldn't write to socket.
          但是服務(wù)器抓不到任何包. 一開始懷疑是連建立連接出的問題, 實(shí)際上服務(wù)器抓不到包也有可能是流在沒有close的時(shí)候就已經(jīng)報(bào)錯(cuò)了.
          如:
          conn.open("url");
          out = conn.openDataOutputStream();//此時(shí)將進(jìn)行與服務(wù)器的三次握手;
                                            //但是如果在out.close()之前出現(xiàn)異常服務(wù)器是抓不到任何包的
          out.write(byte[] bb);

          關(guān)于這個(gè)的解釋應(yīng)該是流的緩沖機(jī)制.
          所以正確的寫法應(yīng)該是捕捉到異常之后在catch塊中把流close掉.
          服務(wù)器端開發(fā)人員一般會(huì)說收不到包所以連接有問題,會(huì)把責(zé)任推給客戶端,抓住這個(gè)證據(jù)在跟服務(wù)器端的同事扯皮時(shí)將處于有利的位置,嘎嘎.
          還有就是要多做小實(shí)驗(yàn), 注意代碼要規(guī)范嚴(yán)格.

          發(fā)現(xiàn)的幾個(gè)問題:

          1. java.io.IOException: Couldn't write to socket

          2. java.io.IOException: Couldn't read from socket

          CMNET聯(lián)網(wǎng)方案:

          CMWAP聯(lián)網(wǎng)方案:

          移動(dòng)資費(fèi)頁的處理:

          一個(gè)通用的HTTP連接封裝:

          posted @ 2008-11-04 16:22 LukeW 閱讀(380) | 評(píng)論 (0)編輯 收藏

          VIM設(shè)置

          vim簡(jiǎn)介
           
          Vim(Vi Improved) 是一個(gè)類似于vi 的文本編輯器,在Vi的基礎(chǔ)上增加了很多新的特性和功能。Vim以其強(qiáng)大的功能和可定制能力

          ,成為L(zhǎng)inux/Unix環(huán)境下開源的最重要的編輯器之一(另一個(gè)是 Emacs),被眾多開發(fā)者所喜愛。筆者此時(shí)所用的是最新的7.1版本

          。
          與大部分其它編輯器不同,進(jìn)入 Vim 后,缺省狀態(tài)下鍵入的字符并不會(huì)插入到所編輯的文件之中。Vim 的模式(mode,可以簡(jiǎn)單地

          理解為“狀態(tài)”)概念非常重要。需要知道,Vim 有以下幾個(gè)模式:
          1)   正常(normal)模式,缺省的編輯模式;下面如果不加特殊說明,提到的命令都直接在正常模式下輸入;任何其它模式中都

          可以通過鍵盤上的 Esc 鍵回到正常模式。
          2)   命令(command)模式,用于執(zhí)行較長(zhǎng)、較復(fù)雜的命令;在正常模式下輸入“:”(一般命令)、“/”(正向搜索)或“?”

          (反向搜索)即可進(jìn)入該模式;命令模式下的命令要輸入回車鍵(Enter)才算完成。
          3)   插入(insert)模式,輸入文本時(shí)使用;在正常模式下鍵入“i”(insert)或“a”(append)即可進(jìn)入插入模式(也有另

          外一些命令,如“c”,也可以進(jìn)入插入模式,但這些命令有其它的作用)。
          4)   可視(visual)模式,用于選定文本塊;可以在正常模式下輸入“v”(小寫)來按字符選定,輸入“V”(大寫)來按行選

          定,或輸入“Ctrl-V”來按方塊選定。
          5)   選擇(select)模式,與普通的 Windows 編輯器較為接近的選擇文本塊的方式;在以可視模式和選擇模式之一選定文本塊之

          后,可以使用“Ctrl-G”切換到另一模式——該模式很少在 Linux 上使用,本文中就不再介紹了。
          ------------------------------------------
          首先 vim ~/.vimrc 打開編輯文件

          [轉(zhuǎn)]
             1、VI或VIM的配置文件的路徑

              發(fā)現(xiàn)/usr/share/vim/vimrc和/etc/vim/vimrc指向是同一個(gè)文件,即vimrc,為vi和vim的配置文件,修改這個(gè)文件即可。這個(gè)路徑在不同的LINUX版本中可能會(huì)不同。

              2、配置顏色

              配軒VI和VIM的顏色顯示,使它能夠高亮度顯示一些特別的單詞,這對(duì)編寫程序很有用。后來打開文件發(fā)現(xiàn)里面其實(shí)已經(jīng)有一行了,只是用引號(hào)注釋掉了,只需 將syntax on 所在行前面的引號(hào)去掉即可?;蛘吡硗猹?dú)立添加一行:syntax on 也行,另外編輯/etc/profile 增加一行alias vi="vim"就行了。

              3、設(shè)置鼠標(biāo)

              使用VI編輯文本時(shí),如果想修文件中改離光標(biāo)較遠(yuǎn)的位置,這時(shí)候想用鼠標(biāo)定位,可默認(rèn)情況下,鼠標(biāo)是不可用的。如果你想使用鼠標(biāo),只需另起一行,寫上:set mouse=a 即可

              4、設(shè)置自動(dòng)縮進(jìn)

              默認(rèn)情況下,VI和VIM都沒有縮進(jìn)的,每換一行,光標(biāo)均定位在頂格,如果你想自動(dòng)對(duì)齊,請(qǐng)將 set autoindent所在行前面的引號(hào)去掉,或者另外添加一行:set autoindent也可。這與配置顏色類似。這樣的設(shè)置的結(jié)果是按回車后新行與上一行自動(dòng)對(duì)齊。

              5、設(shè)置tab的縮進(jìn)量

              如果用python編寫程序,那么行縮進(jìn)量是一個(gè)極其重要的概念,同一個(gè)塊的縮進(jìn)量必須相同。你可能喜歡在行前加空格來表示縮進(jìn),但每次必須敲多次空格 鍵,如果你喜歡用按TAB鍵來表示縮進(jìn),你可能覺得寫的文本或程序不太好看,因?yàn)槟J(rèn)情況下,VI和VIM的TAB縮進(jìn)量比較大(至少六,七個(gè)字符)。設(shè) 置TAB鍵縮進(jìn)量的方法:set shiftwidth=3 你也可以選一 個(gè)你自己喜歡的縮進(jìn)量,比如2,或4.

          ----------------------------------------------

          首先從視覺方面:

          第一個(gè)要做的是縮進(jìn),修改你的配置文件_vimrc,在最后加入set cindent,這樣就設(shè)置了c風(fēng)格的縮進(jìn),在這里縮進(jìn)的大小是shiftwidth的值。

          第二個(gè)要做的是語法高亮,這個(gè)是必須的,在中_vimrc加入syntax enable。

          第三個(gè)要做的字體的設(shè)置,設(shè)置一個(gè)舒服的字體可以讓你編程的時(shí)候舒服好多,用editplus的時(shí)候我就用的Consolas,在中我還是用的這種字體,在_vimrc中加入

          if has(”gui_running”)
          set guifont=Consolas:h9
          endif

          表示運(yùn)行界面的時(shí)候就用這種字體。

          第四,設(shè)置配色方案,可以到點(diǎn)擊這兒下載,然后放到$"vimfiles"colors這個(gè)目錄下,然后在中加入如下配置

          if has(”gui_running”)
          set guifont=Consolas:h9
          ” set color schema
          colorscheme
          colorscheme_name
          endif

          colorscheme_name為你需要設(shè)置的配色方案的名稱。

          接下來是在運(yùn)行程序中用到的:

          第一,使用ctag

          中已經(jīng)帶了Ctags這個(gè)程序。盡管ctags也可以支持其它編輯器,但是它正式支持的只有。Ctags可以幫助程序員很容易地瀏覽源代碼。用下面的命令可以在源代碼的根目錄下創(chuàng)建“tags”文件:

          [/home/brimmer/src]$ ctags -R

          “-R”表示遞歸創(chuàng)建,也就包括源代碼根目錄下的所有子目錄下的源程序。“tags”文件中包括這些對(duì)象的列表:

          l        用#define定義的宏

          l        枚舉型變量的值

          l        函數(shù)的定義、原型和聲明

          l        名字空間(namespace)

          l        類型定義(typedefs)

          l        變量(包括定義和聲明)

          l        類(class)、結(jié)構(gòu)(struct)、枚舉類型(enum)和聯(lián)合(union)

          l        類、結(jié)構(gòu)和聯(lián)合中成員變量或函數(shù)

          用這個(gè)“tags”文件來定位上面這些做了標(biāo)記的對(duì)象,下面介紹一下定位這些對(duì)象的方法:

          1)        用命令行。在運(yùn)行的時(shí)候加上“-t”參數(shù),例如:

          [/home/brimmer/src]$   -t  foo_bar

          這個(gè)命令將打開定義“foo_bar”(變量或函數(shù)或其它)的文件,并把光標(biāo)定位到這一行。

          2)        在編輯器內(nèi)用“:ta”命令,例如:

          :ta foo_bar

          3)        最方便的方法是把光標(biāo)移到變量名或函數(shù)名上,然后按下“Ctrl-]”。用“Ctrl-o”退回原來的地方。

          注意:運(yùn)行的時(shí)候,必須在“tags”文件所在的目錄下運(yùn)行。否則,運(yùn)行的時(shí)候還要用“:set tags=”命令設(shè)定“tags”文件的路徑,這樣才能找到“tags”文件。

          你還可以選擇使用taglist這個(gè)插件,這個(gè)插件可以在右側(cè)顯示函數(shù),變量等的列表

          第二,改正程序中的錯(cuò)誤

          編輯器的環(huán)境下用“:make”(make工具的使用已經(jīng)在我昨天的文章中 提到的云風(fēng)的幾篇文章中詳細(xì)介紹到)就可以編譯程序,當(dāng)然其前提是在當(dāng)前目錄下有Makefile文件。運(yùn)行完“:make”之后,如果程序中有錯(cuò)誤,就 會(huì)顯示出來。這時(shí)候,光標(biāo)會(huì)自動(dòng)指向第一個(gè)出現(xiàn)錯(cuò)誤的地方,而且你還可以看到錯(cuò)誤的提示。然后,你就可以改正錯(cuò)誤,而不用手工找到出錯(cuò)的那一行。記住下面 幾個(gè)有用的命令:

          l        “:cl”列出錯(cuò)誤

          l        “:cn”讓光標(biāo)指向下一個(gè)錯(cuò)誤

          l        “:cp”讓光標(biāo)指向上一個(gè)錯(cuò)誤

          l        “:cnew”從頭開始

          你甚至可以讓識(shí)別出其它編譯器而不是gcc的錯(cuò)誤提示。這對(duì)一些開發(fā)嵌入式系統(tǒng)的程序員這很有用,因?yàn)樗麄兒芸赡苡玫牟皇莋cc而是其它編譯器。通過設(shè)置“errorformat”的值,可以讓識(shí)別出編譯器的出錯(cuò)提示。因?yàn)椴煌木幾g器的出錯(cuò)提示是不同的,所以如果用的不是gcc就要重新設(shè)置。

          errorformat”的值是一個(gè)字符串,它的格式和C語言的scanf的字符串格式相識(shí)。

          gcc的“errorformat”的值為:%f:%l:"%m。其中“%f”表示文件名,“%l”表示行號(hào),“%m”表示出錯(cuò)信息。

          用“:h errorformat”查看詳細(xì)的幫助信息。

          “:h quickfix”、“:h make”、“:h makeprg”、“:h errorfile”查看其它的信息。

          第三,使用快捷鍵

          下面的這些快捷鍵對(duì)程序員很有幫助:
          在函數(shù)中移動(dòng)光標(biāo)

          [[  轉(zhuǎn)到上一個(gè)位于第一列的“{”

          ]]  轉(zhuǎn)到下一個(gè)位于第一列的“{”

          {   轉(zhuǎn)到上一個(gè)空行

          }   轉(zhuǎn)到下一個(gè)空行

          gd  轉(zhuǎn)到當(dāng)前光標(biāo)所指的局部變量的定義

          *   轉(zhuǎn)到當(dāng)前光標(biāo)所指的單詞下一次出現(xiàn)的地方

          #   轉(zhuǎn)到當(dāng)前光標(biāo)所指的單詞上一次出現(xiàn)的地方
          括號(hào)的匹配

          %   用來進(jìn)行小括號(hào)、中括號(hào)和大括號(hào)的匹配。這要看當(dāng)前光標(biāo)指向的是什么符號(hào)了。

          ----------------------------------------------

          一個(gè)ubuntu 下的vimrc配置例子:

          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 一般設(shè)定
          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 設(shè)定默認(rèn)解碼
          set fenc
          =utf-8
          set fencs
          =utf-8,usc-bom,euc-jp,gb18030,gbk,gb2312,cp936

          "設(shè)定搜索是的高亮顯示
          set hlsearch

          " 不要使用vi的鍵盤模式,而是vim自己的
          set nocompatible

          " history文件中需要記錄的行數(shù)
          set history=100

          " 在處理未保存或只讀文件的時(shí)候,彈出確認(rèn)
          set confirm

          " 與windows共享剪貼板
          set clipboard+=unnamed

          " 偵測(cè)文件類型
          filetype on

          " 載入文件類型插件
          filetype plugin on

          " 為特定文件類型載入相關(guān)縮進(jìn)文件
          filetype indent on

          " 保存全局變量
          set viminfo+=!

          " 帶有如下符號(hào)的單詞不要被換行分割
          set iskeyword
          +=_,$,@,%,#,-

          " 語法高亮
          syntax on

          " 高亮字符,讓其不受100列限制
          :highlight OverLength ctermbg
          =red ctermfg=white guibg=red guifg=white
          ":match OverLength '"%101v.*'

          " 狀態(tài)行顏色
          highlight StatusLine guifg=SlateBlue guibg=Yellow
          highlight StatusLineNC guifg=Gray guibg=White

          "高亮當(dāng)前行
          set cursorline

          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 文件設(shè)置
          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 不要備份文件(根據(jù)自己需要取舍)
          set nobackup

          " 不要生成swap文件,當(dāng)buffer被丟棄的時(shí)候隱藏它
          setlocal noswapfile
          set bufhidden=hide

          " 字符間插入的像素行數(shù)目
          set linespace
          =0

          " 增強(qiáng)模式中的命令行自動(dòng)完成操作
          set wildmenu

          " 在狀態(tài)行上顯示光標(biāo)所在位置的行號(hào)和列號(hào)
          set ruler
          set rulerformat
          =%20(%2*%<%f%=" %m%r" %3l" %c" %p%%%)

          " 命令行(在狀態(tài)行下)的高度,默認(rèn)為1,這里是2
          set cmdheight=2

          " 使回格鍵(backspace)正常處理indent, eol, start等
          set backspace
          =2

          " 允許backspace和光標(biāo)鍵跨越行邊界
          set whichwrap+=<,>,h,l

          " 可以在buffer的任何地方使用鼠標(biāo)(類似office中在工作區(qū)雙擊鼠標(biāo)定位)
          set mouse
          =a
          set selection
          =exclusive
          set selectmode
          =mouse,key

          " 啟動(dòng)的時(shí)候不顯示那個(gè)援助索馬里兒童的提示
          set shortmess=atI

          " 通過使用: commands命令,告訴我們文件的哪一行被改變過
          set report
          =0

          " 不讓vim發(fā)出討厭的滴滴聲
          set noerrorbells

          " 在被分割的窗口間顯示空白,便于閱讀
          set fillchars
          =vert:" ,stl:" ,stlnc:"

          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 搜索和匹配
          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 高亮顯示匹配的括號(hào)
          set showmatch

          " 匹配括號(hào)高亮的時(shí)間(單位是十分之一秒)
          set matchtime
          =5

          " 在搜索的時(shí)候不忽略大小寫
          set noignorecase

          " 不要高亮被搜索的句子(phrases)
          "set nohlsearch

          " 在搜索時(shí),輸入的詞句的逐字符高亮(類似firefox的搜索)
          set incsearch

          " 輸入:set list命令是應(yīng)該顯示些啥?
          set listchars=tab:
          "|" ,trail:.,extends:>,precedes:<,eol:$

          " 光標(biāo)移動(dòng)到buffer的頂部和底部時(shí)保持3行距離
          set scrolloff
          =3

          " 不要閃爍
          set novisualbell

          " 我的狀態(tài)行顯示的內(nèi)容(包括文件類型和解碼)
          set statusline
          =%F%m%r%h%w" [FORMAT=%{&ff}]" [TYPE=%Y]" [POS=%l,%v][%p%%]" %{strftime(""%d/%m/%y" -" %H:%M"")}

          " 總是顯示狀態(tài)行
          set laststatus=2

          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 文本格式和排版
          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 自動(dòng)格式化
          set formatoptions=tcrqn

          " 繼承前一行的縮進(jìn)方式,特別適用于多行注釋
          set autoindent

          " 為C程序提供自動(dòng)縮進(jìn)
          set smartindent

          " 使用C樣式的縮進(jìn)
          set cindent

          " 制表符為4
          set tabstop=4

          " 統(tǒng)一縮進(jìn)為4
          set softtabstop
          =4
          set shiftwidth
          =4

          " 不要用空格代替制表符
          set noexpandtab

          " 不要換行
          "set nowrap

          "設(shè)置每行80個(gè)字符自動(dòng)換行
          set textwidth
          =80

          " 在行和段開始處使用制表符
          set smarttab

          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " CTags的設(shè)定
          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 按照名稱排序
          let Tlist_Sort_Type = 
          "name"

          " 在右側(cè)顯示窗口
          let Tlist_Use_Right_Window 
          = 1

          " 壓縮方式
          let Tlist_Compart_Format = 1

          " 如果只有一個(gè)buffer,kill窗口也kill掉buffer
          let Tlist_Exist_OnlyWindow 
          = 1

          " 不要關(guān)閉其他文件的tags
          let Tlist_File_Fold_Auto_Close = 0

          " 不要顯示折疊樹
          let Tlist_Enable_Fold_Column 
          = 1

          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " Autocommands
          """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
          " 只在下列文件類型被偵測(cè)到的時(shí)候顯示行號(hào),普通文本文件不顯示

          if has("autocmd")
             autocmd FileType xml,html,c,cs,java,perl,shell,bash,cpp,python,vim,php,ruby set number
             autocmd FileType xml,html vmap 
          <C-o> <ESC>'<i<!--<ESC>o<ESC>'>o-->
             autocmd FileType java,c,cpp,cs vmap 
          <C-o> <ESC>'<o/*<ESC>'>o*/
             autocmd FileType html,text,php,vim,c,java,xml,bash,shell,perl,python setlocal textwidth
          =80
             autocmd Filetype html,xml,xsl source $VIMRUNTIME
          /plugin/closetag.vim
             autocmd BufReadPost 
          *
                
          " if line("'""") > 0 && line("'""") <= line("$") |
                
          "   exe "normal g`""" |
                
          " endif
          endif 
          " has("autocmd")

          " C/C++的編譯和運(yùn)行
          map <F5> :call CompileRunGcc()<CR>
          func! CompileRunGcc()
          exec 
          "w"
          exec 
          "!make"
          exec 
          "! ./%<"
          endfunc

          " shell script運(yùn)行
          map 
          <F6> :call CompileRunSH()<CR>
          func
          ! CompileRunSH()
          exec 
          "w"
          exec 
          "!chmod a+x %"
          exec 
          "!./%"
          endfunc

          " python運(yùn)行
          map <F7> :call CompileRunPyhton()<CR>
          func! CompileRunPyhton()
          exec 
          "w"
          exec 
          "!chmod a+%"
          exec 
          "!./%"
          endfunc

          " 能夠漂亮地顯示.NFO文件
          set encoding
          =utf-8
          function! SetFileEncodings(encodings)
              let b:myfileencodingsbak
          =&fileencodings
              let 
          &fileencodings=a:encodings
          endfunction
          function! RestoreFileEncodings()
              let 
          &fileencodings=b:myfileencodingsbak
              unlet b:myfileencodingsbak
          endfunction

          au BufReadPre 
          *.nfo call SetFileEncodings('cp437')|set ambiwidth=single
          au BufReadPost 
          *.nfo call RestoreFileEncodings()

          " 高亮顯示普通txt文件(需要txt.vim腳本)
          au BufRead,BufNewFile *  setfiletype txt

          " 用空格鍵來開關(guān)折疊
          set foldenable
          set foldlevel
          =0
          set foldmethod
          =indent
          nnoremap 
          <space> @=((foldclosed(line('.')) < 0? 'zc' : 'zo')<CR>

          " minibufexpl插件的一般設(shè)置
          let g:miniBufExplMapWindowNavVim = 1
          let g:miniBufExplMapWindowNavArrows = 1
          let g:miniBufExplMapCTabSwitchBufs = 1
          let g:miniBufExplModSelTarget = 1

          ----------------------
          一個(gè)相關(guān)帖子
          http://forum.ubuntu.org.cn/viewtopic.php?f=68&t=138212&st=0&sk=t&sd=a

           

          posted @ 2008-11-03 13:02 LukeW 閱讀(1636) | 評(píng)論 (0)編輯 收藏

          servlet過濾器

          servlet過濾器

          1. Servlet過濾器基礎(chǔ)
          Servlet過濾器是Servlet的一種特殊用法,主要用來完成一些通用的操作。比如編碼的過濾,判斷用戶的登陸狀態(tài)等等。Servlet過濾器的適用場(chǎng)合:
          A.認(rèn)證過濾
          B.登錄和審核過濾
          C.圖像轉(zhuǎn)換過濾
          D.?dāng)?shù)據(jù)壓縮過濾
          E.加密過濾
          F.令牌過濾
          G.資源訪問觸發(fā)事件過濾
          Servlet過濾器接口的構(gòu)成:
          所有的Servlet過濾器類都必須實(shí)現(xiàn)javax.servlet.Filter接口。這個(gè)接口含有3個(gè)過濾器類必須實(shí)現(xiàn)的方法:
          方法 說明
          init(FilterConfig cfg) 這是Servlet過濾器的初始化方法,性質(zhì)等同與servlet的init方法。
          doFilter(ServletRequest,ServletResponse,FilterChain) 完成實(shí)際的過濾操作,當(dāng)請(qǐng)求訪問過濾器關(guān)聯(lián)的URL時(shí),Servlet容器將先調(diào)用過濾器的doFilter方法。FilterChain參數(shù)用于訪問后續(xù)過濾器
          destroy() Servlet容器在銷毀過濾器實(shí)例前調(diào)用該方法,這個(gè)方法中可以釋放Servlet過濾器占用的資源。性質(zhì)等同與servlet的destory()方法。
          Servlet過濾器的創(chuàng)建步驟:
          A.實(shí)現(xiàn)javax.servlet.Filter接口的servlet類
          B.實(shí)現(xiàn)init方法,讀取過濾器的初始化函數(shù)
          C.實(shí)現(xiàn)doFilter方法,完成對(duì)請(qǐng)求或過濾的響應(yīng)
          D.調(diào)用FilterChain接口對(duì)象的doFilter方法,向后續(xù)的過濾器傳遞請(qǐng)求或響應(yīng)
          F.在web.xml中配置Filter
          2.使用過濾器處理中文問題
             當(dāng)用用戶登陸頁面輸入帳號(hào)時(shí),如果輸入是中文,后臺(tái)servlet再次輸出這個(gè)內(nèi)容時(shí),可能就會(huì)是亂碼,這是因?yàn)閟erlvet中默認(rèn)是以ISO-8859-1格式編碼的,如果后臺(tái)有多個(gè)Servlet,多個(gè)參數(shù),這樣就不合適,這個(gè)問題,我們可以通過一個(gè)過濾器統(tǒng)一解決,使后臺(tái)的輸出輸出都支持中文!將ISO-8859-1轉(zhuǎn)碼為GBK的那段代碼!
          3.使用過濾器認(rèn)證用戶:
          每個(gè)過濾器也可以配置初始化參數(shù),可以將不需要過濾的地址配置到這個(gè)Filter的配置參數(shù)中,過濾時(shí),如果請(qǐng)求地址在配置參數(shù)中,則放行,這樣 就避免了在程序中硬編碼。每個(gè)Filter中初始化時(shí),都可以得到配置對(duì)象,在Filter中配置二個(gè)不需要過濾的地址,一個(gè)是登陸頁面,一個(gè)是執(zhí)行登陸 認(rèn)證的servlet;
          4.Servlet監(jiān)聽器
          類似與Swing界面應(yīng)用開發(fā),Servlet也可以創(chuàng)建監(jiān)聽器,以對(duì)Servlet容器,或Servlet中以象的事件做出反應(yīng)。Servlet監(jiān)聽器主要有以下幾種:
          ServletRequestListener ,ServletRequestAttributeListener,
          HttpSessionActivationListener ,HttpSessionBindingListener ,
          HttpSessionAttributeListener,HttpSessionListener,
          ServletContextListener等等。
          這些監(jiān)聽器主要用來監(jiān)聽session,request,application這三個(gè)對(duì)象里存取數(shù)據(jù)的變化。
          ----------------------------------------------------------------------------------------------------------------

          servlet API中最重要的一個(gè)功能就是能夠?yàn)閟ervlet和JSP頁面定義過濾器。過濾器提供了某些早期服務(wù)器所支持的非標(biāo)準(zhǔn)“servlet鏈接”的一種功能強(qiáng)大且標(biāo)準(zhǔn)的替代品。
                                                                                                          
               過濾器是一個(gè)程序,它先于與之相關(guān)的servlet或JSP頁面運(yùn)行在服務(wù)器上。過濾器可附加到一個(gè)或多個(gè)servlet或JSP頁面上,并且可以檢查進(jìn)入這些資源的請(qǐng)求信息。在這之后,過濾器可以作如下的選擇:

          1. 以常規(guī)的方式調(diào)用資源(即,調(diào)用servlet或JSP頁面)。

          2.利用修改過的請(qǐng)求信息調(diào)用資源。

          3. 調(diào)用資源,但在發(fā)送響應(yīng)到客戶機(jī)前對(duì)其進(jìn)行修改

          4. 阻止該資源調(diào)用,代之以轉(zhuǎn)到其他的資源,返回一個(gè)特定的狀態(tài)代碼或生成替換輸出。

          過濾器提供了幾個(gè)重要好處 :


                  首先,它以一種模塊化的或可重用的方式封裝公共的行為。你有30個(gè)不同的serlvet或JSP頁面,需要壓縮它們的內(nèi)容以減少下載時(shí)間嗎?沒問題:構(gòu)造一個(gè)壓縮過濾器,然后將它應(yīng)用到30個(gè)資源上即可。

          其次,利用它能夠?qū)⒏呒?jí)訪問決策與表現(xiàn)代碼相分離。這對(duì)于JSP特別有價(jià)值,其中一般希望將幾乎整個(gè)頁面集中在表現(xiàn)上,而不是集中在業(yè)務(wù)邏輯上。例如,希 望阻塞來自某些站點(diǎn)的訪問而不用修改各頁面(這些頁面受到訪問限制)嗎?沒問題:建立一個(gè)訪問限制過濾器并把它應(yīng)用到想要限制訪問的頁面上即可。

               最后,過濾器使你能夠?qū)υS多不同的資源進(jìn)行批量性的更改。你有許多現(xiàn)存資源,這些資源除了公司名要更改外其他的保持不變,能辦到么?沒問題:構(gòu)造一個(gè)串替換過濾器,只要合適就使用它。

               但要注意,過濾器只在與servlet規(guī)范2.3版兼容的服務(wù)器上有作用。如果你的Web應(yīng)用需要支持舊版服務(wù)器,就不能使用過濾器。

          1.   建立基本過濾器

          建立一個(gè)過濾器涉及下列五個(gè)步驟:
          1)建立一個(gè)實(shí)現(xiàn)Filter接口的類。這個(gè)類需要三個(gè)方法,分別是:doFilter、init和destroy。
                 doFilter方法包含主要的過濾代碼(見第2步),init方法建立設(shè)置操作,而destroy方法進(jìn)行清楚。

          2)在doFilter方法中放入過濾行為。doFilter方法的第一個(gè)參數(shù)為ServletRequest對(duì)象。此對(duì)象給過濾器提供了對(duì)進(jìn)入的信息 (包括表單數(shù)據(jù)、cookie和HTTP請(qǐng)求頭)的完全訪問。第二個(gè)參數(shù)為ServletResponse,通常在簡(jiǎn)單的過濾器中忽略此參數(shù)。最后一個(gè)參 數(shù)為FilterChain,如下一步所述,此參數(shù)用來調(diào)用servlet或JSP頁。

          3)調(diào)用FilterChain對(duì)象的doFilter方法。Filter接口的doFilter方法取一個(gè)FilterChain對(duì)象作為它的一個(gè)參 數(shù)。在調(diào)用此對(duì)象的doFilter方法時(shí),激活下一個(gè)相關(guān)的過濾器。如果沒有另一個(gè)過濾器與servlet或JSP頁面關(guān)聯(lián),則servlet或JSP 頁面被激活。

          4)對(duì)相應(yīng)的servlet和JSP頁面注冊(cè)過濾器。在部署描述符文件(web.xml)中使用filter和filter-mapping元素。

          5)禁用激活器servlet。防止用戶利用缺省servlet URL繞過過濾器設(shè)置。

          1.1   建立一個(gè)實(shí)現(xiàn)Filter接口的類
                所有過濾器都必須實(shí)現(xiàn)javax.servlet.Filter。這個(gè)接口包含三個(gè)方法,分別為doFilter、init和destroy。

          public void doFilter(ServletRequset request,
                               ServletResponse response,
                               FilterChain chain)
               thows ServletException, IOException

          每當(dāng)調(diào)用一個(gè)過濾器(即,每次請(qǐng)求與此過濾器相關(guān)的servlet或JSP頁面)時(shí),就執(zhí)行其doFilter方法。正是這個(gè)方法包含了大部分過濾邏輯。 第一個(gè)參數(shù)為與傳入請(qǐng)求有關(guān)的ServletRequest。對(duì)于簡(jiǎn)單的過濾器,大多數(shù)過濾邏輯是基于這個(gè)對(duì)象的。如果處理HTTP請(qǐng)求,并且需要訪問諸 如getHeader或getCookies等在ServletRequest中無法得到的方法,就要把此對(duì)象構(gòu)造成 HttpServletRequest。

          第二個(gè)參數(shù)為ServletResponse。除了在兩個(gè)情形下要使用它以外,通常忽略這個(gè)參數(shù)。首先,如果希望完全阻塞對(duì)相關(guān)servlet或JSP頁 面的訪問??烧{(diào)用response.getWriter并直接發(fā)送一個(gè)響應(yīng)到客戶機(jī)。其次,如果希望修改相關(guān)的servlet或JSP頁面的輸出,可把響 應(yīng)包含在一個(gè)收集所有發(fā)送到它的輸出的對(duì)象中。然后,在調(diào)用serlvet或JSP頁面后,過濾器可檢查輸出,如果合適就修改它,之后發(fā)送到客戶機(jī)。

          DoFilter的最后一個(gè)參數(shù)為FilterChain對(duì)象。對(duì)此對(duì)象調(diào)用doFilter以激活與servlet或JSP頁面相關(guān)的下一個(gè)過濾器。如果沒有另一個(gè)相關(guān)的過濾器,則對(duì)doFilter的調(diào)用激活servlet或JSP本身。

          public void init(FilterConfig config)   thows ServletException

          init方法只在此過濾器第一次初始化時(shí)執(zhí)行,不是每次調(diào)用過濾器都執(zhí)行它。對(duì)于簡(jiǎn)單的過濾器,可提供此方法的一個(gè)空體,但有兩個(gè)原因需要使用init。 首先,F(xiàn)ilterConfig對(duì)象提供對(duì)servlet環(huán)境及web.xml文件中指派的過濾器名的訪問。因此,普遍的辦法是利用init將 FilterConfig對(duì)象存放在一個(gè)字段中,以便doFilter方法能夠訪問servlet環(huán)境或過濾器名.其次,F(xiàn)ilterConfig對(duì)象具 有一個(gè)getInitParameter方法,它能夠訪問部署描述符文件(web.xml)中分配的過濾器初始化參數(shù)。

          public void destroy( )
               大多數(shù)過濾器簡(jiǎn)單地為此方法提供一個(gè)空體,不過,可利用它來完成諸如關(guān)閉過濾器使用的文件或數(shù)據(jù)庫連接池等清除任務(wù)。

          1.2   將過濾行為放入doFilter方法

               doFilter方法為大多數(shù)過濾器地關(guān)鍵部分。每當(dāng)調(diào)用一個(gè)過濾器時(shí),都要執(zhí)行doFilter。對(duì)于大多數(shù)過濾器來說,doFilter執(zhí)行的步驟是 基于傳入的信息的。因此,可能要利用作為doFilter的第一個(gè)參數(shù)提供的ServletRequest。這個(gè)對(duì)象常常構(gòu)造為 HttpServletRequest類型,以提供對(duì)該類的更特殊方法的訪問。

          1.3   調(diào)用FilterChain對(duì)象的doFilter方法
               Filter接口的doFilter方法以一個(gè)FilterChain對(duì)象作為它的第三個(gè)參數(shù)。在調(diào)用該對(duì)象的doFilter方法時(shí),激活下一個(gè)相關(guān)的 過濾器。這個(gè)過程一般持續(xù)到鏈中最后一個(gè)過濾器為止。在最后一個(gè)過濾器調(diào)用其FilterChain對(duì)象的doFilter方法時(shí),激活servlet或 頁面自身。
          但是,鏈中的任意過濾器都可以通過不調(diào)用其FilterChain的doFilter方法中斷這個(gè)過程。在這樣的情況下,不再調(diào)用JSP頁面的serlvet,并且中斷此調(diào)用過程的過濾器負(fù)責(zé)將輸出提供給客戶機(jī)。

          1.4   對(duì)適當(dāng)?shù)膕ervlet和JSP頁面注冊(cè)過濾器

               部署描述符文件的2.3版本引入了兩個(gè)用于過濾器的元素,分別是:filter和filter-mapping。filter元素向系統(tǒng)注冊(cè)一個(gè)過濾對(duì)象,filter-mapping元素指定該過濾對(duì)象所應(yīng)用的URL。

          1.filter元素
          filter元素位于部署描述符文件(web.xml)的前部,所有filter-mapping、servlet或servlet-mapping元素之前。filter元素具有如下六個(gè)可能的子元素:

          1、 icon   這是一個(gè)可選的元素,它聲明IDE能夠使用的一個(gè)圖象文件。
          2、filter-name   這是一個(gè)必需的元素,它給過濾器分配一個(gè)選定的名字。
          3、display-name   這是一個(gè)可選的元素,它給出IDE使用的短名稱。
          4、 description   這也是一個(gè)可選的元素,它給出IDE的信息,提供文本文檔。
          5、 filter-class   這是一個(gè)必需的元素,它指定過濾器實(shí)現(xiàn)類的完全限定名。
          6、 init-param   這是一個(gè)可選的元素,它定義可利用FilterConfig的getInitParameter方法讀取的初始化參數(shù)。單個(gè)過濾器元素可包含多個(gè)init-param元素。

          請(qǐng)注意,過濾是在serlvet規(guī)范2.3版中初次引入的。因此,web.xml文件必須使用DTD的2.3版本。下面介紹一個(gè)簡(jiǎn)單的例子:

            <xml version="1.0" encoding="ISO-8859-1"?>
              
          DOCTYPE web-app PUBLIC
                  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
                   "http://java.sun.com/dtd/web-app_2_3.dtd"
          >

              
          <web-app>
               
          <filter>
                  
          <filter-name>MyFilterfilter-name>
                  
          <filter-class>myPackage.FilterClassfilter-class>
                
          filter>
                

                
          <filter-mapping>...filter-mapping>
               <
          web-app>


          2.filter-mapping元素

              filter-mapping元素位于web.xml文件中filter元素之后serlvet元素之前。它包含如下三個(gè)可能的子元素:

          1、 filter-name   這個(gè)必需的元素必須與用filter元素聲明時(shí)給予過濾器的名稱相匹配。

          2、 url-pattern   此元素聲明一個(gè)以斜杠(/)開始的模式,它指定過濾器應(yīng)用的URL。所有filter-mapping元素中必須提供url-pattern或 servlet-name。但不能對(duì)單個(gè)filter-mapping元素提供多個(gè)url-pattern元素項(xiàng)。如果希望過濾器適用于多個(gè)模式,可重復(fù) 整個(gè)filter-mapping元素。

          3、 servlet-name   此元素給出一個(gè)名稱,此名稱必須與利用servlet元素給予servlet或JSP頁面的名稱相匹配。不能給單個(gè)filter-mapping元素提供 多個(gè)servlet-name元素項(xiàng)。如果希望過濾器適合于多個(gè)servlet名,可重復(fù)這個(gè)filter-mapping元素。
          下面舉一個(gè)例子:

          xml version="1.0" encoding="ISO-8859-1"?>
              
          DOCTYPE web-app PUBLIC
                  
          "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

                  
          "http://java.sun.com/dtd/web-app_2_3.dtd">
              
          <web-app>
                
          <filter>
                  
          <filter-name>MyFilterfilter-name>
                  
          <filter-class>myPackage.FilterClassfilter-class>
                
          filter>
                

                
          <filter-mapping>
                  
          <filter-name>MyFilterfilter-name>
                  
          <url-pattern>/someDirectory/SomePage.jspurl-pattern>
                
          filter-mapping>
              
          web-app>


          1.5   禁用激活器servlet
               在對(duì)資源應(yīng)用過濾器時(shí),可通過指定要應(yīng)用過濾器的URL模式或servlet名來完成。如果提供servlet名,則此名稱必須與web.xml的 servlet元素中給出的名稱相匹配。如果使用應(yīng)用到一個(gè)serlvet的URL模式,則此模式必須與利用web.xml的元素servlet- mapping指定的模式相匹配。但是,多數(shù)服務(wù)器使用“激活器servlet”為servlet體統(tǒng)一個(gè)缺省的URL:http: //host/WebAppPrefix/servlet/ServletName。需要保證用戶不利用這個(gè)URL訪問servlet(這樣會(huì)繞過過濾器 設(shè)置)。
          例如,假如利用filter和filter-mapping指示名為SomeFilter的過濾器應(yīng)用到名為SomeServlet的servlet,則如下:

          <filter>
                
          <filter-name>SomeFilterfilter-name>
                
          <filter-class>somePackage.SomeFilterClassfilter-class>
             <
          filter>
              

              
          <filter-mapping>
                
          <filter-name>SomeFilterfilter-name>
                
          <servlet-name>SomeServletservlet-name>
               <
          filter-mapping>



          接著,用servlet和servlet-mapping規(guī)定URL   http://host/webAppPrefix/Blah 應(yīng)該調(diào)用SomeSerlvet,如下所示:

          <filter>
                
          <filter-name>SomeFilterfilter-name>
                
          <filter-class>somePackage.SomeFilterClassfilter-class>
              
          filter>
              

              
          <filter-mapping>
                
          <filter-name>SomeFilterfilter-name>
                
          <servlet-name>/Blahservlet-name>
               <
          filter-mapping>



          現(xiàn)在,在客戶機(jī)使用URL   http://host/webAppPrefix/Blah 時(shí)就會(huì)調(diào)用過濾器。過濾器不應(yīng)用到
          http://host/webAppPrefix/servlet/SomePackage.SomeServletClass。
          盡管有關(guān)閉激活器的服務(wù)器專用方法。但是,可移植最強(qiáng)的方法時(shí)重新映射Web應(yīng)用鐘的/servlet模式,這樣使所有包含此模式的請(qǐng)求被送到相同的 servlet中。為了重新映射此模式,首先應(yīng)該建立一個(gè)簡(jiǎn)單的servlet,它打印一條錯(cuò)誤消息,或重定向用戶到頂層頁。然后,使用servlet和 servlet-mapping元素發(fā)送包含/servlet模式的請(qǐng)求到該servlet。程序清單9-1給出了一個(gè)簡(jiǎn)短的例子。

          程序清單9-1 web.xml(重定向缺省servlet URL的摘錄)

           xml version="1.0" encoding="ISO-8859-1"?>
              
          DOCTYPE web-app PUBLIC
                   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
                   "http://java.sun.com/dtd/web-app_2_3.dtd"
          >

              
          <web-app>
              

              
          <servlet>
                
          <servlet-name>Errorservlet-name>
                
          <servlet-class>somePackage.ErrorServletservlet-class>
              
          servlet>
              

              
          <servlet-mapping>
                
          <servlet-name>Errorservlet-name>
                
          <url-pattern>/servlet/*url-pattern>
              
          servlet-mapping>
              

              <
          web-app>

          -------------------------------------------------------------------------------------------
          解決亂碼

          web.xml加配置

          <!--   過濾器 -->
           <filter>
            <filter-name>Filter</filter-name>
            <filter-class>
             com.util.EncodingFilter<!-- 過濾器類 -->
            </filter-class>
            <init-param>
             <param-name>Encoding</param-name>
             <param-value>gb2312</param-value>
            </init-param>
           </filter>
           <filter-mapping>
            <filter-name>Filter</filter-name>
            <url-pattern>/*</url-pattern>
           </filter-mapping>

          EncodingFilter.java

          package com.hibernate.util;

          import java.io.IOException;

          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;

          public class EncodingFilter implements Filter {
           protected FilterConfig config;

           protected String Encoding = null;

           public void init(FilterConfig config) throws ServletException {

            this.config = config;
            this.Encoding = config.getInitParameter("Encoding");

           }

           public void doFilter(ServletRequest request, ServletResponse response,
             FilterChain chain) throws IOException, ServletException {

            if (request.getCharacterEncoding() == null) {
             if (Encoding != null) {
              request.setCharacterEncoding(Encoding);
              response.setCharacterEncoding(Encoding);
             }
            }
            chain.doFilter(request,response);
           }
           public void destroy() {}
          }

          OK!!!

          ----------------------------------------------------------------------------------------------------

          很簡(jiǎn)單的過濾器,就是為了記錄一個(gè)url的請(qǐng)求時(shí)間 filter:
          1. package com.javaeye.wqf;  
          2. import javax.servlet.*;  
          3.   
          4. public class CounterFilter implements Filter {  
          5.     public void doFilter(ServletRequest request, ServletResponse response,  
          6.             FilterChain chain) throws IOException, ServletException {  
          7.         long start = System.currentTimeMillis();  
          8.         System.out.println("Filter start at "+start);  
          9.         chain.doFilter(request, response);  
          10.         long end = System.currentTimeMillis();  
          11.         System.out.println("Filter end at "+end);  
          12.     } 



          1. <filter>  
          2.     <filter-name>test</filter-name>  
          3.     <filter-class>com.javaeye.wqf.CounterFilter</filter-class>  
          4. </filter>  
          5.   
          6. <filter-mapping>  
          7.     <filter-name>test</filter-name>  
          8.     <url-pattern>/*</url-pattern>  
          9. </filter-mapping> 
          一般情況下是沒什么問題,但是當(dāng)我下載一個(gè)稍微大的文件時(shí),跳出確認(rèn)窗口,如果選擇的是cancel,
          就會(huì)發(fā)現(xiàn)filter并沒有返回,也就是說
          1. System.out.println("Filter end at "+end); 
          并沒有執(zhí)行. 原因是:

          chain.doFilter(request, response);  
          執(zhí)行到這里時(shí)會(huì)從這里調(diào)用剩下的filter和servlet,所以這個(gè)調(diào)用將會(huì)是一個(gè)很長(zhǎng)的過程。
          在這個(gè)調(diào)用里,將會(huì)完全通過request和resonse去操作連接,取得/發(fā)送數(shù)據(jù),如果連接出現(xiàn)異常,將直接彈出Exception
          你的代碼里沒有捕獲異常,所以如果出現(xiàn)異常,chain.doFilter后面的就不會(huì)執(zhí)行。
          可以把chain.doFilter放到try finally結(jié)構(gòu)中,保證后續(xù)會(huì)被執(zhí)行




          posted @ 2008-10-28 14:58 LukeW 閱讀(348) | 評(píng)論 (0)編輯 收藏

          Android應(yīng)用程序剖析

          Anatomy of an Android Application


          There are four building blocks to an Android application:
          • Activity
          • Intent Receiver
          • Service
          • Content Provider

          Not every application needs to have all four, but your application will be written with some combination of these.

          Once you have decided what components you need for your application, you should list them in a file called AndroidManifest.xml. This is an XML file where you declare the components of your application and what their capabilities and requirements are. See the Android manifest file documentation for complete details.

          Activity
          Activities are the most common of the four Android building blocks. An activity is usually a single screen in your application. Each activity is implemented as a single class that extends the Activity base class. Your class will display a user interface composed of Views and respond to events. Most applications consist of multiple screens. For example, a text messaging application might have one screen that shows a list of contacts to send messages to, a second screen to write the message to the chosen contact, and other screens to review old messages or change settings. Each of these screens would be implemented as an activity. Moving to another screen is accomplished by a starting a new activity. In some cases an activity may return a value to the previous activity -- for example an activity that lets the user pick a photo would return the chosen photo to the caller.

          When a new screen opens, the previous screen is paused and put onto a history stack. The user can navigate backward through previously opened screens in the history. Screens can also choose to be removed from the history stack when it would be inappropriate for them to remain. Android retains history stacks for each application launched from the home screen.

          Intent and Intent Filters
          Android uses a special class called an Intent to move from screen to screen. An intent describes what an application wants done. The two most important parts of the intent data structure are the action and the data to act upon. Typical values for action are MAIN (the front door of the activity), VIEW, PICK, EDIT, etc. The data is expressed as a URI. For example, to view contact information for a person, you would create an intent with the VIEW action and the data set to a URI representing that person.

          There is a related class called an IntentFilter. While an intent is effectively a request to do something, an intent filter is a description of what intents an activity (or intent receiver, see below) is capable of handling. An activity that is able to display contact information for a person would publish an IntentFilter that said that it knows how to handle the action VIEW when applied to data representing a person. Activities publish their IntentFilters in the AndroidManifest.xml file.

          Navigating from screen to screen is accomplished by resolving intents. To navigate forward, an activity calls startActivity(myIntent). The system then looks at the intent filters for all installed applications and picks the activity whose intent filters best matches myIntent. The new activity is informed of the intent, which causes it to be launched. The process of resolving intents happens at run time when startActivity is called, which offers two key benefits:

          * Activities can reuse functionality from other components simply by making a request in the form of an Intent
          * Activities can be replaced at any time by a new Activity with an equivalent IntentFilter


          Intent Receiver
          You can use an IntentReceiver when you want code in your application to execute in reaction to an external event, for example, when the phone rings, or when the data network is available, or when it's midnight. Intent receivers do not display a UI, although they may use the NotificationManager to alert the user if something interesting has happened. Intent receivers are registered in AndroidManifest.xml, but you can also register them from code using Context.registerReceiver(). Your application does not have to be running for its intent receivers to be called; the system will start your application, if necessary, when an intent receiver is triggered. Applications can also send their own intent broadcasts to others with Context.broadcastIntent().
          Service

          A Service is code that is long-lived and runs without a UI. A good example of this is a media player playing songs from a play list. In a media player application, there would probably be one or more activities that allow the user to choose songs and start playing them. However, the music playback itself should not be handled by an activity because the user will expect the music to keep playing even after navigating to a new screen. In this case, the media player activity could start a service using Context.startService() to to run in the background to keep the music going. The system will then keep the music playback service running until it has finished. (You can learn more about the priority given to services in the system by reading Lifecycle of an Android Application.) Note that you can connect to a service (and start it if it's not already running) with the Context.bindService() method. When connected to a service, you can communicate with it through an interface exposed by the service. For the music service, this might allow you to pause, rewind, etc.

          Content Provider
          Applications can store their data in files, an SQLite database, or any other mechanism that makes sense. A content provider, however, is useful if you want your application's data to be shared with other applications. A content provider is a class that implements a standard set of methods to let other applications store and retrieve the type of data that is handled by that content provider.

          To get more details on content providers, see Accessing Content Providers.

          posted @ 2008-10-07 16:22 LukeW 閱讀(274) | 評(píng)論 (0)編輯 收藏

          HTTP協(xié)議中的Tranfer-Encoding:chunked編碼解析

              當(dāng)不能預(yù)先確定報(bào)文體的長(zhǎng)度時(shí),不可能在頭中包含Content-Length域來指明報(bào)文體長(zhǎng)度,此時(shí)就需要通過Transfer-Encoding域來確定報(bào)文體長(zhǎng)度。
              通常情況下,Transfer-Encoding域的值應(yīng)當(dāng)為chunked,表明采用chunked編碼方式來進(jìn)行報(bào)文體的傳輸。chunked編碼是HTTP/1.1 RFC里定義的一種編碼方式,因此所有的HTTP/1.1應(yīng)用都應(yīng)當(dāng)支持此方式。
              chunked編碼的基本方法是將大塊數(shù)據(jù)分解成多塊小數(shù)據(jù),每塊都可以自指定長(zhǎng)度,其具體格式如下(BNF文法):
              Chunked-Body   = *chunk            //0至多個(gè)chunk
                               last-chunk         //最后一個(gè)chunk
                               trailer            //尾部
                               CRLF               //結(jié)束標(biāo)記符

             chunk          = chunk-size [ chunk-extension ] CRLF  
                                  chunk-data CRLF
             chunk-size     = 1*HEX
             last-chunk     = 1*("0") [ chunk-extension ] CRLF

             chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
             chunk-ext-name = token
             chunk-ext-val  = token | quoted-string
             chunk-data     = chunk-size(OCTET)
             trailer        = *(entity-header CRLF)     
             
              解釋:
              Chunked-Body表示經(jīng)過chunked編碼后的報(bào)文體。報(bào)文體可以分為chunk, last-chunk,trailer和結(jié)束符四部分。chunk的數(shù)量在報(bào)文體中最少可以為0,無上限;每個(gè)chunk的長(zhǎng)度是自指定的,即,起始的數(shù) 據(jù)必然是16進(jìn)制數(shù)字的字符串,代表后面chunk-data的長(zhǎng)度(字節(jié)數(shù))。這個(gè)16進(jìn)制的字符串第一個(gè)字符如果是“0”,則表示chunk- size為0,該chunk為last-chunk,無chunk-data部分。可選的chunk-extension由通信雙方自行確定,如果接收者 不理解它的意義,可以忽略。
              trailer是附加的在尾部的額外頭域,通常包含一些元數(shù)據(jù)(metadata, meta means "about information"),這些頭域可以在解碼后附加在現(xiàn)有頭域之后。
              實(shí)例分析:
              下面分析用ethereal抓包使用Firefox與某網(wǎng)站通信的結(jié)果(從頭域結(jié)束符后開始):
          Address  0..........................  f
          000c0                                31
          000d0    66 66 63 0d 0a ...............   // ASCII碼:1ffc"r"n, chunk-data數(shù)據(jù)起始地址為000d5
                   很明顯,“1ffc”為第一個(gè)chunk的chunk-size,轉(zhuǎn)換為int為8188.由于1ffc后馬上就是
                   CRLF,因此沒有chunk-extension.chunk-data的起始地址為000d5, 計(jì)算可知下一塊chunk的起始
                   地址為000d5+1ffc + 2=020d3,如下:
          020d0    .. 0d 0a 31 66 66 63 0d 0a .... // ASCII碼:"r"n1ffc"r"n
                   前一個(gè)0d0a是上一個(gè)chunk的結(jié)束標(biāo)記符,后一個(gè)0d0a則是chunk-size和chunk-data的分隔符。
                   此塊chunk的長(zhǎng)度同樣為8188, 依次類推,直到最后一塊
          100e0                          0d 0a 31
          100f0    65 61 39 0d 0a......            //ASII碼:"r"n"1ea9"r"n
                   此塊長(zhǎng)度為0x1ea9 = 7849, 下一塊起始為100f5 + 1ea9 + 2 = 11fa0,如下:
          100a0    30 0d 0a 0d 0a                  //ASCII碼:0"r"n"r"n
                   “0”說明當(dāng)前chunk為last-chunk, 第一個(gè)0d 0a為chunk結(jié)束符。第二個(gè)0d0a說明沒有trailer部分,整個(gè)Chunk-body結(jié)束。
              解碼流程:
              對(duì)chunked編碼進(jìn)行解碼的目的是將分塊的chunk-data整合恢復(fù)成一塊作為報(bào)文體,同時(shí)記錄此塊體的長(zhǎng)度。
              RFC2616中附帶的解碼流程如下:(偽代碼)
              length := 0         //長(zhǎng)度計(jì)數(shù)器置0
              read chunk-size, chunk-extension (if any) and CRLF      //讀取chunk-size, chunk-extension
                                                                    //和CRLF
              while(chunk-size > 0 )   {            //表明不是last-chunk
                    read chunk-data and CRLF            //讀chunk-size大小的chunk-data,skip CRLF
                    append chunk-data to entity-body     //將此塊chunk-data追加到entity-body后
                    read chunk-size and CRLF          //讀取新chunk的chunk-size 和 CRLF
              }
              read entity-header      //entity-header的格式為name:valueCRLF,如果為空即只有CRLF
              while (entity-header not empty)   //即,不是只有CRLF的空行
              {
                 append entity-header to existing header fields
                 read entity-header
              }
              Content-Length:=length      //將整個(gè)解碼流程結(jié)束后計(jì)算得到的新報(bào)文體length
                                           //作為Content-Length域的值寫入報(bào)文中
              Remove "chunked" from Transfer-Encoding  //同時(shí)從Transfer-Encoding中域值去除chunked這個(gè)標(biāo)記
              length最后的值實(shí)際為所有chunk的chunk-size之和,在上面的抓包實(shí)例中,一共有八塊chunk-size為0x1ffc(8188)的chunk,剩下一塊為0x1ea9(7849),加起來一共73353字節(jié)。
              注:對(duì)于上面例子中前幾個(gè)chunk的大小都是8188,可能是因?yàn)?"1ffc" 4字節(jié),""r"n"2字節(jié),加上塊尾一個(gè)""r"n"2字節(jié)一共8字節(jié),因此一個(gè)chunk整體為8196,正好可能是發(fā)送端一次TCP發(fā)送的緩存大小。

          posted @ 2008-09-24 18:03 LukeW 閱讀(2960) | 評(píng)論 (2)編輯 收藏

          HTTP Connections

          HTTP Connections
          最近初涉網(wǎng)絡(luò)編程,分析了下HTTP協(xié)議,下面為第一篇關(guān)于HTTP連接控制方面的學(xué)習(xí)日志,主要參考RFC2616,肯定有疏漏之處,還望指出。
          HTTP協(xié)議是位于傳輸層之上的應(yīng)用層協(xié)議,其網(wǎng)絡(luò)層基礎(chǔ)通常是TCP協(xié)議。TCP協(xié)議是面向連接和流的,因此連接的狀態(tài)和控制對(duì)于HTTP協(xié)議而言相當(dāng)重要。同時(shí),HTTP是基于報(bào)文的,因此如何確定報(bào)文長(zhǎng)度也是協(xié)議中比較重要的一點(diǎn)。
          Persistent Connections持久連接
          目的
              在使用持久連接前,HTTP協(xié)議規(guī)定為獲取每個(gè)URL資源都需要使用單獨(dú)的一個(gè)TCP連接,這增加了HTTP服務(wù)端的負(fù)載,引起互聯(lián)網(wǎng)擁塞。例如內(nèi)嵌圖片以及其他類似數(shù)據(jù)的使用要求一個(gè)客戶端在很短時(shí)間內(nèi)向同一個(gè)服務(wù)端發(fā)起多個(gè)請(qǐng)求。
          使用持久連接的優(yōu)點(diǎn):
          減少TCP連接數(shù)量
          在一個(gè)連接上實(shí)現(xiàn)HTTP請(qǐng)求和應(yīng)答的流水,即允許客戶端發(fā)出多個(gè)請(qǐng)求,而不必在接收到前一請(qǐng)求的應(yīng)答后才發(fā)出下一請(qǐng)求,極大減少時(shí)間消耗
          后續(xù)請(qǐng)求延遲減少,無需再在TCP握手上耗時(shí)
          可以更加優(yōu)雅地實(shí)現(xiàn)HTTP協(xié)議,由于持續(xù)連接的存在無需報(bào)告錯(cuò)誤后無需關(guān)閉連接,因此客戶端可使用最新的協(xié)議特性發(fā)出請(qǐng)求,如果接收到表示錯(cuò)誤的應(yīng)答,則換用更舊的語義。

          總體描述
          HTTP/1.1和之前版本的顯著區(qū)別是HTTP/1.1默認(rèn)使用持久連接。即,除非服務(wù)端在應(yīng)答中明確指出,客戶端應(yīng)當(dāng)假定服務(wù)端會(huì)維持一個(gè)持久連接,即使從服務(wù)端收到的應(yīng)答是報(bào)告錯(cuò)誤。
          持 久連接對(duì)關(guān)閉TCP連接的行為提供信號(hào)量機(jī)制支持。這個(gè)信號(hào)量是在HTTP頭中的Connection域設(shè)置,注意Client向Proxy發(fā)出請(qǐng)求時(shí)該 域可能被Proxy-Connection域替換。一旦close信號(hào)被表明,客戶端絕不能再通過該連接發(fā)送更多的請(qǐng)求。

          協(xié)商(Negotiation)
          HTTP/1.1 服務(wù)端可以假定HTTP/1.1客戶端會(huì)維持持久連接,除非請(qǐng)求中Connection域的值是"close".同樣的,如果服務(wù)端打算在送出應(yīng)答后立即 關(guān)閉連接,它應(yīng)當(dāng)在應(yīng)答中包含同樣的Connection域。(TCP連接關(guān)閉是雙向的,此時(shí)TCP進(jìn)入半關(guān)閉狀態(tài))
          同樣的,HTTP/1.1客戶端可以期望連接是持久的,除非如前所述收到表示連接關(guān)閉的應(yīng)答。當(dāng)然,也可以主動(dòng)發(fā)出一個(gè)包含Connection:close的請(qǐng)求以表明終止連接。
          無論客戶端還是服務(wù)端發(fā)出的報(bào)文包含Connection:close,則該請(qǐng)求均為連接上的最后一個(gè)請(qǐng)求(服務(wù)端發(fā)出此應(yīng)答后關(guān)閉,因此不可能接收更多的請(qǐng)求)
          報(bào)文傳輸長(zhǎng)度
              為保證持久性,連接上的報(bào)文都必須有一個(gè)自定義的報(bào)文傳輸長(zhǎng)度(否則必須通過連接的關(guān)閉表示報(bào)文結(jié)束,因?yàn)門CP連接是面向流的),確定的規(guī)則按優(yōu)先級(jí)由高到低排列如下:
              報(bào)文傳輸長(zhǎng)度指報(bào)文中出現(xiàn)的報(bào)文體的長(zhǎng)度(即,不包括頭長(zhǎng)度,因?yàn)閳?bào)文頭的結(jié)束可通過連續(xù)兩個(gè)CRLF確定)
          1.任何絕不能包含報(bào)文體(如1xx,204,304)的應(yīng)答消息總是以頭域后的第一個(gè)空行結(jié)束,無視頭中所有的entity類型域的設(shè)置,包括Content-Length域。
          2.Transfer-Encoding域出現(xiàn),其值為除"identify"以外的其他值,則用"chunked"傳輸編碼方式確定傳輸長(zhǎng)度,具體方式留待下篇分析。
          3.Content- Length域出現(xiàn),且Transfer-Encoding域未出現(xiàn)(出現(xiàn)則忽略Content-Length域)。Content-Length域的值 為十進(jìn)制數(shù)的字節(jié)序,如Content-Length:1234,則1、2、3、4是分別作為一個(gè)octet傳輸?shù)?,因此需要atoi轉(zhuǎn)換成數(shù)值。
          4.如果報(bào)文使用了"multipart/byteranges"的媒體類型,且沒對(duì)傳輸長(zhǎng)度做前面的指明,則這種自分割的媒體類型定義了傳輸長(zhǎng)度。具體參見Range頭域的說明。
          5.服務(wù)端關(guān)閉連接(此方法不可用于客戶端發(fā)出的請(qǐng)求報(bào)文,因?yàn)榭蛻舳岁P(guān)閉連接則使得服務(wù)端無法發(fā)送應(yīng)答).
              為保持和HTTP/1.0的兼容性, 包含報(bào)文體的HTTP/1.1請(qǐng)求必須包含合法的Content-Length頭域,除非明確知道服務(wù)端是HTTP/1.1兼容的.如果請(qǐng)求包含消息體, 而沒有Content-Length域,那么如果服務(wù)端無法確定消息長(zhǎng)度時(shí),它會(huì)返回400(無效請(qǐng)求),或者堅(jiān)持獲取合法Content-Length 而返回411(要求包含長(zhǎng)度).

              所有接收實(shí)體的HTTP/1.1應(yīng)用程序必須接受"chunked"傳輸編碼, 這樣允許當(dāng)報(bào)文長(zhǎng)度無法預(yù)先確定時(shí)可以運(yùn)用此機(jī)制獲取報(bào)文長(zhǎng)度.
              報(bào)文不能同時(shí)包含Content-Length頭域和非"identity" Transfer-Encoding.如果出現(xiàn)了, Content-Length域必須被忽略.
              當(dāng)Content-Length域在允許報(bào)文體的報(bào)文中存在時(shí), 其域值必須嚴(yán)格等于消息體中的8比特字節(jié).HTTP/1.1 user agent 必須在接收并檢測(cè)到一個(gè)錯(cuò)誤的長(zhǎng)度時(shí)提醒用戶.
              以上方法中,最常見的還是使用Content-Length域表示報(bào)文體長(zhǎng)度,Transfer-Encoding需要按格式解碼才能還原出發(fā)送編碼前的報(bào)文。

          流水
              支持持久連接的客戶端可以流水發(fā)送請(qǐng)求,服務(wù)端必須按發(fā)送的順序發(fā)送應(yīng)答。
              假定持久連接和連接后即可流水的客戶端應(yīng)當(dāng)做好在第一次流水失敗后重新嘗試此連接。在這樣的嘗試中,在確定連接是持久的之前,客戶端不能再流水。
              客戶端同樣必須準(zhǔn)備好在服務(wù)端送回所有相關(guān)應(yīng)答前就關(guān)閉連接時(shí)重發(fā)請(qǐng)求。
              不應(yīng)流水non-idempotent方法

          Proxy Servers
              對(duì)于代理服務(wù)端而言,正確實(shí)現(xiàn)Connection頭域指定的屬性尤為重要。
              代理服務(wù)端必須分立通告它的客戶端和連接的原始服務(wù)端持久連接的屬性,每個(gè)持久連接設(shè)置僅針對(duì)一個(gè)傳輸連接。
             
          實(shí)踐考量
              超時(shí)值,服務(wù)端通常會(huì)為每個(gè)連接維護(hù)一個(gè)定時(shí)器,一旦某個(gè)連接不活躍超過一定時(shí)間值,服務(wù)端會(huì)關(guān)閉此連接。考慮到一個(gè)客戶端可能通過代理服務(wù)端發(fā)出更多連接,代理服務(wù)端通常會(huì)將超時(shí)值設(shè)置得更高。
              還有一些關(guān)于從異步關(guān)閉中恢復(fù)的討論。

          報(bào)文傳輸要求
              使用TCP流控制來解決服務(wù)端臨時(shí)負(fù)載過高問題,而不是簡(jiǎn)單的依賴客戶端重連而關(guān)閉連接。
              監(jiān)視連接情況以獲取錯(cuò)誤狀態(tài)消息
              關(guān)于使用100(繼續(xù))狀態(tài)碼
              100狀態(tài)碼用于客戶端發(fā)送請(qǐng)求體之前測(cè)試是否可以發(fā)送該請(qǐng)求,對(duì)于Proxy,有以下要求:
          1.如果代理服務(wù)端接收到包含Expect頭域值為"100-continue"的請(qǐng)求, 而不明確知道下一跳服務(wù)不支持HTTP/1.1以上版本, 則它必須轉(zhuǎn)發(fā)這個(gè)請(qǐng)求, 包括Expect頭域.
          2.如果代理知道下一跳服務(wù)端為HTTP/1.0或者更低版本, 則它不能轉(zhuǎn)發(fā)此請(qǐng)求, 且必須以407應(yīng)答客戶端.
          3.如果明確知道發(fā)出請(qǐng)求的客戶端版本為HTTP/1.0或者更低,則代理服務(wù)端絕不能轉(zhuǎn)發(fā)100應(yīng)答,這條規(guī)則凌駕于轉(zhuǎn)發(fā)1xx應(yīng)答的一般準(zhǔn)則.

          Connection頭域說明
          BNF文法:
              Connection = "Connection" ":" 1#(connection-token)
              connection-token  = token
             
          Connection頭域中的token用于指定對(duì)于特定連接有意義的選項(xiàng),因此proxy在轉(zhuǎn)發(fā)前要掃描此域,從頭中去除和token同名的域。例如Connection:Range,則要去掉Range域。
              HTTP/1.1定義了close這個(gè)token,發(fā)送者用此token表示在完成這個(gè)報(bào)文所屬請(qǐng)求/應(yīng)答的收發(fā)后連接將關(guān)閉。


          posted @ 2008-09-24 18:01 LukeW 閱讀(554) | 評(píng)論 (1)編輯 收藏

          關(guān)于斷點(diǎn)續(xù)傳的調(diào)研

          一些討論:
          http://topic.csdn.net/t/20061214/22/5231907.html

          posted @ 2008-09-24 17:57 LukeW 閱讀(221) | 評(píng)論 (0)編輯 收藏

          Serializing an Image

          Serializing an Image

          Creating an image from an array of data is an easy task, but to create a byte-array of data from an image is a little more complicated. But it's required if you want to send a modified image to a server.

          To create a byte-array of data from an image, we can use the getRGB(..) method in the image class in MIDP 2.0. From the getRGB method we get an int-array of data containing all the ARGB values of each pixel in the image. Integers in java are four bytes, so we need to split each int value into four byte values.

          To mask out each of the bytes in the int we can use the 'AND &' operator and the 'shift-right >>' operator. Here's an example:

          int ARGB = 0xFFFFFFFF;  // AARRGGBB 
          int a = (ARGB & 0xFF000000);
          int r = (ARGB & 0x00FF0000);
          int g = (ARGB & 0x0000FF00);
          int b = (ARGB & 0x000000FF);
          // Here we move each bit to the right.
          a = (a >> 24); // a = 0x000000FF
          r = (r >> 16); // r = 0x000000FF
          g = (g >> 8); // g = 0x000000FF
          b = b;        // b = 0x000000FF

          When we convert the integer to a byte, there are some problems since there are only signed bytes in Java. A byte may contain values between –128 and 127 and from our integer we'll have a value between 0 and 255.

          Here are some conversion examples:

          Integer val 127 = byte val 127. 
          Integer val 128 = byte val –128.
          Integer val 255 = byte val –1.
          byte ba = (byte)(a);  // if a=0x000000FF (255), then ba = -1
          byte br = (byte)(r);
          byte bg = (byte)(g);
          byte bb = (byte)(b);

          We have to loop though each pixel in the image and get each pixel value to our byte-array. When that's done, we can send the image to a server where we can convert the byte-array back to a integer-array and then show our picture.

          So, when we convert the byte back to an integer we have to check if the byte value is less than zero.

          Int a, r, g, b;
          If(ba<0)
               a = 256 – a;

          Now our new integer value will be between 0 and 255 and we just have to use the 'shift-left <<' operator and add the values together to get our new int-array.

          a = (a << 24);
          r = (r << 16);
          g = (g << 8);
          b = (b);
            0xFF000000 (a)
          + 0x00FF0000 (r)
          + 0x0000FF00 (g)
          + 0x000000FF (b)
          = 0xFFFFFFFF (argb)
          int ARGB = a+r+g+b;

          After the integer-array is recreated we can use the createRGBImage(..) method in the Image class to create our image.

          Be aware that the byte-array is quite large as it contains all of the ARGB values for each pixel. If an image is 100*60 px, where each pixel is four bytes, the byte array will be 24kb.

          ImageBytearryConvert.rar

          posted @ 2008-09-11 17:09 LukeW 閱讀(267) | 評(píng)論 (0)編輯 收藏

          HTTP頭信息

          HTTP(HyperTextTransferProtocol)是超文本傳輸協(xié)議的縮寫,它用于傳送WWW方式的數(shù)據(jù),關(guān)于HTTP 協(xié)議的詳細(xì)內(nèi)容請(qǐng)參 考RFC2616。HTTP協(xié)議采用了請(qǐng)求/響應(yīng)模型。客戶端向服務(wù)器發(fā)送一個(gè)請(qǐng)求,請(qǐng)求頭包含請(qǐng)求的方法、URI、協(xié)議版本、以及包含請(qǐng)求修飾符、客戶 信息和內(nèi)容的類似于MIME的消息結(jié)構(gòu)。服務(wù)器以一個(gè)狀態(tài)行作為響應(yīng),相應(yīng)的內(nèi)容包括消息協(xié)議的版本,成功或者錯(cuò)誤編碼加上包含服務(wù)器信息、實(shí)體元信息以 及可能的實(shí)體內(nèi)容。

          通常HTTP消息包括客戶機(jī)向服務(wù)器的請(qǐng)求消息和服務(wù)器向客戶機(jī)的響應(yīng)消息。這兩種類型的消息由一個(gè)起始行, 一個(gè)或者多個(gè)頭域,一個(gè)只是頭域結(jié)束的空行和可 選的消息體組成。HTTP的頭域包括通用頭,請(qǐng)求頭,響應(yīng)頭和實(shí)體頭四個(gè)部分。每個(gè)頭域由一個(gè)域名,冒號(hào)(:)和域值三部分組成。域名是大小寫無關(guān)的,域 值前可以添加任何數(shù)量的空格符,頭域可以被擴(kuò)展為多行,在每行開始處,使用至少一個(gè)空格或制表符。

          通用頭域
          通用頭 域包含請(qǐng)求和響應(yīng)消息都支持的頭域,通用頭域包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。對(duì)通用頭域的擴(kuò)展要求通訊雙方都支持此擴(kuò) 展,如果存在不支持的通用頭域,一般將會(huì)作為實(shí)體頭域處理。下面簡(jiǎn)單介紹幾個(gè)在UPnP消息中使用的通用頭域。


            Cache-Control頭域
          Cache -Control指定請(qǐng)求和響應(yīng)遵循的緩存機(jī)制。在請(qǐng)求消息或響應(yīng)消息中設(shè)置 Cache-Control并不會(huì)修改另一個(gè)消息處理過程中的緩存處理過程。請(qǐng)求時(shí)的緩存指令包括no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached,響應(yīng)消息中的指令包括public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。各個(gè)消息中的指令含義如 下:

          Public指示響應(yīng)可被任何緩存區(qū)緩存。
          Private指示對(duì)于單個(gè)用戶的整個(gè)或部分響應(yīng)消息,不能被共享緩存處理。這允許服務(wù)器僅僅描述當(dāng)用戶的部分響應(yīng)消息,此響應(yīng)消息對(duì)于其他用戶的請(qǐng)求無效。
          no-cache指示請(qǐng)求或響應(yīng)消息不能緩存
          no-store用于防止重要的信息被無意的發(fā)布。在請(qǐng)求消息中發(fā)送將使得請(qǐng)求和響應(yīng)消息都不使用緩存。
          max-age指示客戶機(jī)可以接收生存期不大于指定時(shí)間(以秒為單位)的響應(yīng)。
          min-fresh指示客戶機(jī)可以接收響應(yīng)時(shí)間小于當(dāng)前時(shí)間加上指定時(shí)間的響應(yīng)。
          max-stale指示客戶機(jī)可以接收超出超時(shí)期間的響應(yīng)消息。如果指定max-stale消息的值,那么客戶機(jī)可以接收超出超時(shí)期指定值之內(nèi)的響應(yīng)消息。


            Date頭域
          Date頭域表示消息發(fā)送的時(shí)間,時(shí)間的描述格式由rfc822定義。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的時(shí)間表示世界標(biāo)準(zhǔn)時(shí),換算成本地時(shí)間,需要知道用戶所在的時(shí)區(qū)。

            Pragma頭域
            Pragma頭域用來包含實(shí)現(xiàn)特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1協(xié)議中,它的含義和Cache- Control:no-cache相同。

          請(qǐng)求消息
          請(qǐng)求消息的第一行為下面的格式:
          MethodSPRequest-URISPHTTP-VersionCRLFMethod 表示對(duì)于Request-URI完成的方法,這個(gè)字段是大小寫敏感的,包括OPTIONS、GET、HEAD、POST、PUT、DELETE、 TRACE。方法GET和HEAD應(yīng)該被所有的通用WEB服務(wù)器支持,其他所有方法的實(shí)現(xiàn)是可選的。GET方法取回由Request-URI標(biāo)識(shí)的信息。 HEAD方法也是取回由Request-URI標(biāo)識(shí)的信息,只是可以在響應(yīng)時(shí),不返回消息體。POST方法可以請(qǐng)求服務(wù)器接收包含在請(qǐng)求中的實(shí)體信息,可 以用于提交表單,向新聞組、BBS、郵件群組和數(shù)據(jù)庫發(fā)送消息。

          SP表示空格。Request-URI遵循URI格式,在此字段 為星 號(hào)(*)時(shí),說明請(qǐng)求并不用于某個(gè)特定的資源地址,而是用于服務(wù)器本身。HTTP- Version表示支持的HTTP版本,例如為HTTP/1.1。CRLF表示換行回車符。請(qǐng)求頭域允許客戶端向服務(wù)器傳遞關(guān)于請(qǐng)求或者關(guān)于客戶機(jī)的附加 信息。請(qǐng)求頭域可能包含下列字段Accept、Accept-Charset、Accept- Encoding、Accept-Language、Authorization、From、Host、If-Modified-Since、If- Match、If-None-Match、If-Range、If-Range、If-Unmodified-Since、Max-Forwards、 Proxy-Authorization、Range、Referer、User-Agent。對(duì)請(qǐng)求頭域的擴(kuò)展要求通訊雙方都支持,如果存在不支持的請(qǐng) 求頭域,一般將會(huì)作為實(shí)體頭域處理。

            典型的請(qǐng)求消息:
          GET http://download.microtool.de:80/somedata.exe
          Host: download.microtool.de
          Accept:*/*
          Pragma: no-cache
          Cache-Control: no-cache
          Referer: http://download.microtool.de/
          User-Agent:Mozilla/4.04[en](Win95;I;Nav)
          Range:bytes=554554-

          上例第一行表示HTTP客戶端(可能是瀏覽器、下載程序)通過GET方法獲得指定URL下的文件。棕色的部分表示請(qǐng)求頭域的信息,綠色的部分表示通用頭部分。

            Host頭域
            Host頭域指定請(qǐng)求資源的Intenet主機(jī)和端口號(hào),必須表示請(qǐng)求url的原始服務(wù)器或網(wǎng)關(guān)的位置。HTTP/1.1請(qǐng)求必須包含主機(jī)頭域,否則系統(tǒng)會(huì)以400狀態(tài)碼返回。

            Referer頭域
          Referer 頭域允許客戶端指定請(qǐng)求uri的源資源地址,這可以允許服務(wù)器生成回退鏈表,可用來登陸、優(yōu)化cache等。他也允許廢除的或錯(cuò)誤的連接由于維護(hù)的目的被 追蹤。如果請(qǐng)求的uri沒有自己的uri地址,Referer不能被發(fā)送。如果指定的是部分uri地址,則此地址應(yīng)該是一個(gè)相對(duì)地址。

            Range頭域
          Range頭域可以請(qǐng)求實(shí)體的一個(gè)或者多個(gè)子范圍。例如,
          表示頭500個(gè)字節(jié):bytes=0-499
          表示第二個(gè)500字節(jié):bytes=500-999
          表示最后500個(gè)字節(jié):bytes=-500
          表示500字節(jié)以后的范圍:bytes=500-
          第一個(gè)和最后一個(gè)字節(jié):bytes=0-0,-1
          同時(shí)指定幾個(gè)范圍:bytes=500-600,601-999

          但是服務(wù)器可以忽略此請(qǐng)求頭,如果無條件GET包含Range請(qǐng)求頭,響應(yīng)會(huì)以狀態(tài)碼206(PartialContent)返回而不是以200 (OK)。

            User-Agent頭域
          User-Agent頭域的內(nèi)容包含發(fā)出請(qǐng)求的用戶信息。

          響應(yīng)消息
          響應(yīng)消息的第一行為下面的格式:
          HTTP-VersionSPStatus-CodeSPReason-PhraseCRLF

          HTTP -Version表示支持的HTTP版本,例如為HTTP/1.1。Status- Code是一個(gè)三個(gè)數(shù)字的結(jié)果代碼。Reason-Phrase給Status-Code提供一個(gè)簡(jiǎn)單的文本描述。Status-Code主要用于機(jī)器自 動(dòng)識(shí)別,Reason-Phrase主要用于幫助用戶理解。Status-Code的第一個(gè)數(shù)字定義響應(yīng)的類別,后兩個(gè)數(shù)字沒有分類的作用。第一個(gè)數(shù)字可 能取5個(gè)不同的值:

          1xx:信息響應(yīng)類,表示接收到請(qǐng)求并且繼續(xù)處理
          2xx:處理成功響應(yīng)類,表示動(dòng)作被成功接收、理解和接受
          3xx:重定向響應(yīng)類,為了完成指定的動(dòng)作,必須接受進(jìn)一步處理
          4xx:客戶端錯(cuò)誤,客戶請(qǐng)求包含語法錯(cuò)誤或者是不能正確執(zhí)行
          5xx:服務(wù)端錯(cuò)誤,服務(wù)器不能正確執(zhí)行一個(gè)正確的請(qǐng)求

          響應(yīng)頭域允許服務(wù)器傳遞不能放在狀態(tài)行的附加信息,這些域主要描述服務(wù)器的信息和 Request-URI進(jìn)一步的信息。響應(yīng)頭域包含Age、Location、Proxy-Authenticate、Public、Retry- After、Server、Vary、Warning、WWW-Authenticate。對(duì)響應(yīng)頭域的擴(kuò)展要求通訊雙方都支持,如果存在不支持的響應(yīng)頭 域,一般將會(huì)作為實(shí)體頭域處理。

          典型的響應(yīng)消息:

          HTTP/1.0200OK
          Date:Mon,31Dec200104:25:57GMT
          Server:Apache/1.3.14(Unix)
          Content-type:text/html
          Last-modified:Tue,17Apr200106:46:28GMT
          Etag:"a030f020ac7c01:1e9f"
          Content-length:39725426
          Content-range:bytes554554-40279979/40279980

          上例第一行表示HTTP服務(wù)端響應(yīng)一個(gè)GET方法。棕色的部分表示響應(yīng)頭域的信息,綠色的部分表示通用頭部分,紅色的部分表示實(shí)體頭域的信息。

            Location響應(yīng)頭
          Location響應(yīng)頭用于重定向接收者到一個(gè)新URI地址。

            Server響應(yīng)頭
          Server響應(yīng)頭包含處理請(qǐng)求的原始服務(wù)器的軟件信息。此域能包含多個(gè)產(chǎn)品標(biāo)識(shí)和注釋,產(chǎn)品標(biāo)識(shí)一般按照重要性排序。

            實(shí)體
          請(qǐng)求消息和響應(yīng)消息都可以包含實(shí)體信息,實(shí)體信息一般由實(shí)體頭域和實(shí)體組成。實(shí)體頭域包含關(guān)于實(shí)體的原信息,實(shí)體頭包括Allow、Content- Base、Content-Encoding、Content-Language、 Content-Length、Content-Location、Content-MD5、Content-Range、Content-Type、 Etag、Expires、Last-Modified、extension-header。extension-header允許客戶端定義新的實(shí)體 頭,但是這些域可能無法未接受方識(shí)別。實(shí)體可以是一個(gè)經(jīng)過編碼的字節(jié)流,它的編碼方式由Content-Encoding或Content-Type定 義,它的長(zhǎng)度由Content-Length或Content-Range定義。

            Content-Type實(shí)體頭
          Content-Type實(shí)體頭用于向接收方指示實(shí)體的介質(zhì)類型,指定HEAD方法送到接收方的實(shí)體介質(zhì)類型,或GET方法發(fā)送的請(qǐng)求介質(zhì)類型 Content-Range實(shí)體頭
          Content-Range實(shí)體頭用于指定整個(gè)實(shí)體中的一部分的插入位置,他也指示了整個(gè)實(shí)體的長(zhǎng)度。在服務(wù)器向客戶返回一個(gè)部分響應(yīng),它必須描述響應(yīng)覆蓋的范圍和整個(gè)實(shí)體長(zhǎng)度。一般格式:
          Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-legth 


          例如,傳送頭500個(gè)字節(jié)次字段的形式:Content-Range:bytes0- 499/1234如果一個(gè)http消息包含此節(jié)(例如,對(duì)范圍請(qǐng)求的響應(yīng)或?qū)σ幌盗蟹秶闹丿B請(qǐng)求),Content-Range表示傳送的范圍, Content-Length表示實(shí)際傳送的字節(jié)數(shù)。

            Last-modified實(shí)體頭

          應(yīng)答頭 說明
          Allow 服務(wù)器支持哪些請(qǐng)求方法(如GET、POST等)。
          Content-Encoding 文 檔的編碼(Encode)方法。只有在解碼之后才可以得到Content-Type頭指定的內(nèi)容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的 下載時(shí)間。Java的GZIPOutputStream可以很方便地進(jìn)行g(shù)zip壓縮,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet應(yīng)該通過查看Accept-Encoding頭(即request.getHeader("Accept- Encoding"))檢查瀏覽器是否支持gzip,為支持gzip的瀏覽器返回經(jīng)gzip壓縮的HTML頁面,為其他瀏覽器返回普通頁面。
          Content-Length 表 示內(nèi)容長(zhǎng)度。只有當(dāng)瀏覽器使用持久HTTP連接時(shí)才需要這個(gè)數(shù)據(jù)。如果你想要利用持久連接的優(yōu)勢(shì),可以把輸出文檔寫入 ByteArrayOutputStram,完成后查看其大小,然后把該值放入Content-Length頭,最后通過 byteArrayStream.writeTo(response.getOutputStream()發(fā)送內(nèi)容。
          Content-Type 表示后面的文檔屬于什么MIME類型。Servlet默認(rèn)為text/plain,但通常需要顯式地指定為text/html。由于經(jīng)常要設(shè)置Content-Type,因此HttpServletResponse提供了一個(gè)專用的方法setContentTyep。
          Date 當(dāng)前的GMT時(shí)間。你可以用setDateHeader來設(shè)置這個(gè)頭以避免轉(zhuǎn)換時(shí)間格式的麻煩。
          Expires 應(yīng)該在什么時(shí)候認(rèn)為文檔已經(jīng)過期,從而不再緩存它?
          Last-Modified 文 檔的最后改動(dòng)時(shí)間??蛻艨梢酝ㄟ^If-Modified-Since請(qǐng)求頭提供一個(gè)日期,該請(qǐng)求將被視為一個(gè)條件GET,只有改動(dòng)時(shí)間遲于指定時(shí)間的文檔 才會(huì)返回,否則返回一個(gè)304(Not Modified)狀態(tài)。Last-Modified也可用setDateHeader方法來設(shè)置。
          Location 表示客戶應(yīng)當(dāng)?shù)侥睦锶ヌ崛∥臋n。Location通常不是直接設(shè)置的,而是通過HttpServletResponse的sendRedirect方法,該方法同時(shí)設(shè)置狀態(tài)代碼為302。
          Refresh 表示瀏覽器應(yīng)該在多少時(shí)間之后刷新文檔,以秒計(jì)。除了刷新當(dāng)前文檔之外,你還可以通過setHeader("Refresh", "5; URL=http://host/path")讓瀏覽器讀取指定的頁面。
          注 意這種功能通常是通過設(shè)置HTML頁面HEAD區(qū)的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">實(shí)現(xiàn),這是因?yàn)椋詣?dòng)刷新或重定向?qū)τ谀切┎荒苁褂肅GI或Servlet的 HTML編寫者十分重要。但是,對(duì)于Servlet來說,直接設(shè)置Refresh頭更加方便。

          注意Refresh的意義是“N秒之后 刷新本頁面或訪問指定頁面”,而不是“每隔N秒刷新本頁面或訪問指定頁面”。因此,連續(xù)刷新要求每次都發(fā)送一個(gè)Refresh頭,而發(fā)送204狀態(tài)代碼則 可以阻止瀏覽器繼續(xù)刷新,不管是使用Refresh頭還是<META HTTP-EQUIV="Refresh" ...>。

          注意Refresh頭不屬于HTTP 1.1正式規(guī)范的一部分,而是一個(gè)擴(kuò)展,但Netscape和IE都支持它。
          Server 服務(wù)器名字。Servlet一般不設(shè)置這個(gè)值,而是由Web服務(wù)器自己設(shè)置。
          Set-Cookie 設(shè)置和頁面關(guān)聯(lián)的Cookie。Servlet不應(yīng)使用response.setHeader("Set-Cookie", ...),而是應(yīng)使用HttpServletResponse提供的專用方法addCookie。參見下文有關(guān)Cookie設(shè)置的討論。
          WWW-Authenticate 客 戶應(yīng)該在Authorization頭中提供什么類型的授權(quán)信息?在包含401(Unauthorized)狀態(tài)行的應(yīng)答中這個(gè)頭是必需的。例如, response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。
          注意Servlet一般不進(jìn)行這方面的處理,而是讓W(xué)eb服務(wù)器的專門機(jī)制來控制受密碼保護(hù)頁面的訪問(例如.htaccess)。

          posted @ 2008-09-10 12:05 LukeW 閱讀(242) | 評(píng)論 (0)編輯 收藏

          j2me獲取系統(tǒng)信息

          在J2ME開發(fā)中,我們經(jīng)常需要和手機(jī)系統(tǒng)進(jìn)行交互,獲得一些和系統(tǒng)相關(guān)的信息,在J2ME API設(shè)計(jì)中,提供了一系列的系統(tǒng)屬性
          表1   CLDC、MIDP和JTWI屬性
          屬性名稱
          屬性作用
          microedition.profiles
          代表手機(jī)支持的MIDP版本,返回格式值為“MIDP-1.0”或“MIDP-2.0”
          microedition.configuration
          代表手機(jī)支持的CLDC版本,返回格式值為“CLDC-1.0”或“CLDC-2.0”
          microedition.locale
          代表手機(jī)所在的國家或地區(qū),返回值格式為“en-US”
          microedition.platform
          代表手機(jī)的品牌和型號(hào),Nokia手機(jī)的返回值格式為“Nokia6310i/4.42”
          microedition.encoding
          代表手機(jī)默認(rèn)的字符集名稱,返回值格式為“ISO-8859-1”
          microedition.commports
          代表手機(jī)可以使用的串口列表,返回值中各個(gè)串口之間使用逗號(hào)分隔
          microedition.hostname
          MIDP2.0定義,代表本地主機(jī)名稱,需要手機(jī)支持。
          microedition.jtwi.version
          代表手機(jī)支持的JTWI版本,值必須是“1.0”
           表2 可選包屬性
          屬性名稱
          屬性作用
          microedition.media.version
          代表手機(jī)支持的MMAPI版本,如果不支持則返回null
          microedition.pim.version
          代表手機(jī)支持的PIM API版本,如果不支持則返回null
          microedition.m3g.version
          代表手機(jī)支持的M3G API版本,如果不支持則返回null
          microedition.location.version
          代表手機(jī)支持的Location API版本,如果不支持則返回null
          Bluetooth.api.version
          代表手機(jī)支持的BT API版本,如果不支持則返回null
          microedition.io.file.
          FileConnection.version
          代表手機(jī)支持的FC API版本,如果不支持則返回null
          microedition.global.version
          代表手機(jī)支持的Mobile Internationalization API(JSR-238)版本,如果不支持則返回null
          microedition.chapi.version
          代表手機(jī)支持的CH(Content Handler) API(JSR211)版本,如果不支持則返回null
          microedition.sip.version
          代表手機(jī)支持的SIP API版本,如果不支持則返回null
           表3 MMAPI屬性
          屬性名稱
          屬性作用
          supports.mixing
          代表手機(jī)是否支持混音(同時(shí)播放多個(gè)Player),返回值為“true”或“false”
          supports.audio.capture
          代表手機(jī)是否支持聲音捕獲(錄音),返回值為“true”或“false”
          supports.video.capture
          代表手機(jī)是否支持視頻捕獲(錄像),返回值為“true”或“false”
          supports.recording
          代表手機(jī)是否支持記錄(record),返回值為“true”或“false”
          audio.encodings
          代表手機(jī)支持的聲音格式,返回值格式為“encoding=audio/wav”,多個(gè)格式之間使用至少一個(gè)空格進(jìn)行間隔
          video.encodings
          代表手機(jī)支持的視頻格式,返回值格式為“encoding=video/3gpp”,多個(gè)格式之間使用至少一個(gè)空格進(jìn)行間隔
          video.snapshot.encodings
          代表手機(jī)使用getSnapshot方法獲得的視頻快照格式,返回值格式為“encoding=png”,多個(gè)格式之間使用至少一個(gè)空格進(jìn)行間隔
          streamable.contents
          代表手機(jī)支持的流媒體格式,返回null代表不支持
          表4 Wireless Messaging API屬性
          屬性名稱
          屬性作用
          wireless.messaging.sms.smsc
          代表手機(jī)發(fā)送短信時(shí)的短信服務(wù)中心號(hào)碼
          表5 FileConnection API
          屬性名稱
          屬性作用
          fileconn.dir.photos
          代表手機(jī)中存儲(chǔ)照片和其它圖片的目錄,例如“file:///c:/My files/ Images /”
          fileconn.dir.videos
          代表手機(jī)中存儲(chǔ)視頻的目錄,例如“file:///c:/My files/Video clips/”
          fileconn.dir.tones
          代表手機(jī)中存儲(chǔ)聲音的目錄,例如“file:///c:/My files/Tones/”
          fileconn.dir.memorycard
          代表手機(jī)中存儲(chǔ)卡的根目錄。例如“file:///d:/”
          fileconn.dir.private
          (Nokia S40不支持) 
          代表手機(jī)中MIDlet的私有工作目錄,例如“file:///c:/System/MIDlets/[1015f294]/scratch”
          fileconn.dir.photos.name
          代表手機(jī)中圖片目錄的名稱,例如“Images”
          fileconn.dir.videos.name
          代表手機(jī)中視頻目錄的名稱,例如“Video clips”
          fileconn.dir.tones.name
          代表手機(jī)中聲音目錄的名稱,例如“Sound clips”
          file.separator
          代表手機(jī)中的文件分隔符,例如“/”
          fileconn.dir.memorycard.name
          代表手機(jī)中存儲(chǔ)卡的名稱,例如“Memory card”
           使用這些屬性,可以獲得在程序運(yùn)行過程中需要的很多和系統(tǒng)相關(guān)的信息,也可以使用表2中的屬性來獲得手機(jī)是否支持對(duì)應(yīng)的可選包等信息。
          實(shí)際使用示例:String name = System.getProperty(“microedition.platform”);

          注意:如果需要獲得JVM或jad文件中的信息,需要使用MIDlet類中的getAppProperty方法,其屬性名則需要查閱jad文件的設(shè)定,和本文所述的屬性名無關(guān)。

          posted @ 2008-08-28 16:43 LukeW 閱讀(288) | 評(píng)論 (0)編輯 收藏

          HTTP請(qǐng)求頭信息

          HTTP客戶程序(例如瀏覽器),向服務(wù)器發(fā)送請(qǐng)求的時(shí)候必須指明請(qǐng)求類型(一般是GET或者POST)。如有必要,客戶程序還可以選擇發(fā)送其他的請(qǐng)求 頭。大多數(shù)請(qǐng)求頭并不是必需的,但Content-Length除外。對(duì)于POST請(qǐng)求來說Content-Length必須出現(xiàn)。

          下面是一些最常見的請(qǐng)求頭:

          Accept:瀏覽器可接受的MIME類型。
          Accept-Charset:瀏覽器可接受的字符集。
          Accept-Encoding:瀏覽器能夠進(jìn)行解碼的數(shù)據(jù)編碼方式,比如gzip。Servlet能夠向支持gzip的瀏覽器返回經(jīng)gzip編碼的HTML頁面。許多情形下這可以減少5到10倍的下載時(shí)間。
          Accept-Language:瀏覽器所希望的語言種類,當(dāng)服務(wù)器能夠提供一種以上的語言版本時(shí)要用到。
          Authorization:授權(quán)信息,通常出現(xiàn)在對(duì)服務(wù)器發(fā)送的WWW-Authenticate頭的應(yīng)答中。
          Connection: 表示是否需要持久連接。如果Servlet看到這里的值為“Keep-Alive”,或者看到請(qǐng)求使用的是HTTP 1.1(HTTP 1.1默認(rèn)進(jìn)行持久連接),它就可以利用持久連接的優(yōu)點(diǎn),當(dāng)頁面包含多個(gè)元素時(shí)(例如Applet,圖片),顯著地減少下載所需要的時(shí)間。要實(shí)現(xiàn)這一點(diǎn), Servlet需要在應(yīng)答中發(fā)送一個(gè)Content-Length頭,最簡(jiǎn)單的實(shí)現(xiàn)方法是:先把內(nèi)容寫入ByteArrayOutputStream,然 后在正式寫出內(nèi)容之前計(jì)算它的大小。
          Content-Length:表示請(qǐng)求消息正文的長(zhǎng)度。
          Cookie:這是最重要的請(qǐng)求頭信息之一,參見后面《Cookie處理》一章中的討論。
          From:請(qǐng)求發(fā)送者的email地址,由一些特殊的Web客戶程序使用,瀏覽器不會(huì)用到它。
          Host:初始URL中的主機(jī)和端口。
          If-Modified-Since:只有當(dāng)所請(qǐng)求的內(nèi)容在指定的日期之后又經(jīng)過修改才返回它,否則返回304“Not Modified”應(yīng)答。
          Pragma:指定“no-cache”值表示服務(wù)器必須返回一個(gè)刷新后的文檔,即使它是代理服務(wù)器而且已經(jīng)有了頁面的本地拷貝。
          JAVA手機(jī)網(wǎng)[www.cnjm.net]

          Referer:包含一個(gè)URL,用戶從該URL代表的頁面出發(fā)訪問當(dāng)前請(qǐng)求的頁面。
          User-Agent:瀏覽器類型,如果Servlet返回的內(nèi)容與瀏覽器類型有關(guān)則該值非常有用。
          UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE瀏覽器所發(fā)送的非標(biāo)準(zhǔn)的請(qǐng)求頭,表示屏幕大小、顏色深度、操作系統(tǒng)和CPU類型。
          有關(guān)HTTP頭完整、詳細(xì)的說明,請(qǐng)參見http://www.w3.org/Protocols/ 的HTTP規(guī)范。

          java 讀取方法

            Enumeration headerNames = request.getHeaderNames();
                   while(headerNames.hasMoreElements()) {
                       String headerName = (String)headerNames.nextElement();
                       out.println("<p>"+headerName+"  "+request.getHeader(headerName)+"</p>");
                   }

          posted @ 2008-08-20 13:58 LukeW 閱讀(167) | 評(píng)論 (0)編輯 收藏

          期待eclipse RCP:Design, Coding and Packaging 第二版

          eclipse_rcp_book_cover

          《Eclipse Rich Client Platform – Design, Coding and Packaging》是在Eclipse 3.1發(fā)布以后,針對(duì) Eclipse RCP 平臺(tái)的一本非常重要,也非常有用的書。 最近,這本書的作者們開始了第二版的編寫,將以最新的 Eclipse 3.4 為基礎(chǔ),并且預(yù)計(jì)在08年年底正式發(fā)布。 新書的作者透露,第二版中除了以3.4為基礎(chǔ),還將加入很多新東西:

          非常期待著這本書。

          posted @ 2008-08-20 10:13 LukeW 閱讀(140) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 扬州市| 思南县| 深圳市| 长治市| 屏边| 昭觉县| 牙克石市| 上蔡县| 阿图什市| 九寨沟县| 佛坪县| 唐海县| 英德市| 麟游县| 武安市| 无极县| 龙井市| 汝城县| 灵璧县| 古田县| 大同市| 根河市| 乐都县| 武定县| 韶关市| 星座| 米泉市| 玉溪市| 福清市| 桃园县| 弥勒县| 托克逊县| 汉中市| 调兵山市| 武冈市| 泸西县| 牡丹江市| 普洱| 客服| 固原市| 北川|