小菜毛毛技術(shù)分享

          與大家共同成長

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks

          #

          前不久做的一個筆記本BIOS相關(guān)的項目,操作對BOIS文件里面的內(nèi)容時進行較多的位運算,于是順手整理了一份位運算相關(guān)的內(nèi)容。
             Java 定義的位運算(bitwise operators )直接對整數(shù)類型的位進行操作,這些整數(shù)類型包括long,int,short,char,and byte 。
             所有的整數(shù)類型(除了char 類型之外)都是有符號的整數(shù)。這意味著他們既能表示正數(shù),又能表示負(fù)數(shù)。Java 使用采用補碼來表示負(fù)數(shù)。
             為什么采用補碼嗎?這是考慮到零的交叉(zero crossing )問題。
             原碼:
             將最高位作為符號位(以0代表正,1代表負(fù)),其余各位代表數(shù)值本身的絕對值(以二進制表示)。這個時候有一個問題:表示0的時候正0和負(fù)0表示并不一 樣,所以在計算機中沒有采用原碼的表示形式。
             反碼:
             一個數(shù)如果為正,則它的反碼與原碼相同;一個數(shù)如果為負(fù),則符號位為1,其余各位是對原碼取反。問題和上面一樣的。所以,計算機中也沒有采用反碼來表示數(shù) 字。
             補碼:
             一個數(shù)如果為正,則它的原碼、反碼、補碼相同;一個數(shù)如果為負(fù),則符號位為1,其余各位是對原碼取反,然后再加1。也就是通過將與其對應(yīng)的正數(shù)的二進制代 碼取反(即將1變成0,將0變成1),然后對其結(jié)果加1。例如,-42就是通過將42的二進制代碼的各個位取反,即對00101010 取反得到11010101 ,然后再加1,得到11010110 ,即-42 。要對一個負(fù)數(shù)解碼,首先對其所有的位取反,然后加1。例如-42,或11010110 取反后為00101001 ,或41,然后加1,這樣就得到了42。
             在計算機中,如果我們用1個字節(jié)表示一個數(shù),一個字節(jié)有8位,超過8位就進1,在內(nèi)存中情況為:1 00000000。進位1被丟棄。這種情況,我們叫溢出。在計算機中,假定byte 類型的值零為0000 0000,反碼為1111 1111 補碼為1 0000 0000,在計算-0的補碼的時候因為溢出,導(dǎo)致-0和+0是一樣的表示,所以計算機中采用補碼的形式表示數(shù)字。
          數(shù)的最大值和最小值:由于最高位為符號位,所以最大值和最小值時要去掉最高位。如一個byte為8位.最大值為0111 1111 ,即 (2的7次方) -1 = 127.最小值為1000 0000,即-( 2的7次方) =-128。char為無符號數(shù),沒有符號位,所以最小值為0,最大值為1111 1111 1111 1111 ,即(2的16次方) -1。

          移位運算符
          包括:
          “>> 右移,高位補符號位”;
          “>>> 無符號右移,高位補0”;
          “<< 左移”;

          例子:
          -5>>3=-1
          1111 1111 1111 1111 1111 1111 1111 1011
          1111 1111 1111 1111 1111 1111 1111 1111
          其結(jié)果與 Math.floor((double)-5/(2*2*2)) 完全相同。

          -5<<3=-40
          1111 1111 1111 1111 1111 1111 1111 1011
          1111 1111 1111 1111 1111 1111 1101 1000
          其結(jié)果與 -5*2*2*2 完全相同。

          5>>3=0
          0000 0000 0000 0000 0000 0000 0000 0101
          0000 0000 0000 0000 0000 0000 0000 0000
          其結(jié)果與 5/(2*2*2) 完全相同。

          5<<3=40
          0000 0000 0000 0000 0000 0000 0000 0101
          0000 0000 0000 0000 0000 0000 0010 1000
          其結(jié)果與 5*2*2*2 完全相同。

          -5>>>3=536870911
          1111 1111 1111 1111 1111 1111 1111 1011
          0001 1111 1111 1111 1111 1111 1111 1111

          無論正數(shù)、負(fù)數(shù),它們的右移、左移、無符號右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。
          一個有趣的現(xiàn)象是,把 1 左移 31 位再右移 31 位,其結(jié)果為 -1。
          0000 0000 0000 0000 0000 0000 0000 0001
          1000 0000 0000 0000 0000 0000 0000 0000
          1111 1111 1111 1111 1111 1111 1111 1111

          位邏輯運算符
          包括:
          & 與;
          | 或;
          ~ 非(也叫做求反);
          ^ 異或

          “& 與”、“| 或”、“~ 非”是基本邏輯運算,由此可以演變出“與非”、“或非”、“與或非”復(fù)合邏輯運算。“^ 異或”是一種特殊的邏輯運算,對它求反可以得到“同或”,所以“同或”邏輯也叫“異或非”邏輯。

          例子:
          5&3=1
          0000 0000 0000 0000 0000 0000 0000 0101
          0000 0000 0000 0000 0000 0000 0000 0011
          0000 0000 0000 0000 0000 0000 0000 0001

          -5&3=1
          1111 1111 1111 1111 1111 1111 1111 1011
          0000 0000 0000 0000 0000 0000 0000 0011
          0000 0000 0000 0000 0000 0000 0000 0011

          5|3=7
          0000 0000 0000 0000 0000 0000 0000 0101
          0000 0000 0000 0000 0000 0000 0000 0011
          0000 0000 0000 0000 0000 0000 0000 0111

          -5|3=-5
          1111 1111 1111 1111 1111 1111 1111 1011
          0000 0000 0000 0000 0000 0000 0000 0011
          1111 1111 1111 1111 1111 1111 1111 1011

          ~5=-6
          0000 0000 0000 0000 0000 0000 0000 0101
          1111 1111 1111 1111 1111 1111 1111 1010

          ~-5=4
          1111 1111 1111 1111 1111 1111 1111 1011
          0000 0000 0000 0000 0000 0000 0000 0100

          5^3=6
          0000 0000 0000 0000 0000 0000 0000 0101
          0000 0000 0000 0000 0000 0000 0000 0011
          0000 0000 0000 0000 0000 0000 0000 0110

          -5^3=-8
          1111 1111 1111 1111 1111 1111 1111 1011
          0000 0000 0000 0000 0000 0000 0000 0011
          1111 1111 1111 1111 1111 1111 1111 1000

          參考:
          http://blog.csdn.net/zdmilan/archive/2005/10/30/519634.aspx
          posted @ 2010-05-18 12:02 小菜毛毛 閱讀(363) | 評論 (0)編輯 收藏

          應(yīng)用程序服務(wù)器通過各種協(xié)議,可以包括HTTP,把商業(yè)邏輯暴露給客戶端應(yīng)用程序。Web服務(wù)器主要是處理向瀏覽器發(fā)送HTML以供瀏覽,而應(yīng)用程序服務(wù) 器提供訪問商業(yè)邏輯的途徑以供客戶端應(yīng)用程序使用。應(yīng)用程序使用此商業(yè)邏輯就象你調(diào)用對象的一個方法一樣。
          通俗的講,Web服務(wù)器傳送(serves)頁面使瀏覽器可以瀏覽,然而應(yīng)用程序服務(wù)器提供的是客戶端應(yīng)用程序可以調(diào)用(call)的方法 (methods)。確切一點,你可以說:Web服務(wù)器專門處理HTTP請求(request),但是應(yīng)用程序服務(wù)器是通過很多協(xié)議來為應(yīng)用程序提供 (serves)商業(yè)邏輯(business logic)。

          下面讓我們來細(xì)細(xì)道來:

          Web服務(wù)器 (Web Server)

          Web服務(wù)器可以解析(handles)HTTP協(xié)議。當(dāng)Web服務(wù)器接收到一個HTTP請求(request),會返回一個HTTP響應(yīng) (response),例如送回一個HTML頁面。為了處理一個請求(request),Web服務(wù)器可以響應(yīng)(response)一個靜態(tài)頁面或圖片, 進行頁面跳轉(zhuǎn)(redirect),或者把動態(tài)響應(yīng)(dynamic response)的產(chǎn)生委托(delegate)給一些其它的程序例如CGI腳本,JSP(JavaServer Pages)腳本,servlets,ASP(Active Server Pages)腳本,服務(wù)器端(server-side)JavaScript,或者一些其它的服務(wù)器端(server-side)技術(shù)。無論它們(譯者 注:腳本)的目的如何,這些服務(wù)器端(server-side)的程序通常產(chǎn)生一個HTML的響應(yīng)(response)來讓瀏覽器可以瀏覽。

          要知道,Web服務(wù)器的代理模型(delegation model)非常簡單。當(dāng)一個請求(request)被送到Web服務(wù)器里來時,它只單純的把請求(request)傳遞給可以很好的處理請求 (request)的程序(譯者注:服務(wù)器端腳本)。Web服務(wù)器僅僅提供一個可以執(zhí)行服務(wù)器端(server-side)程序和返回(程序所產(chǎn)生的)響 應(yīng)(response)的環(huán)境,而不會超出職能范圍。服務(wù)器端(server-side)程序通常具有事務(wù)處理(transaction processing),數(shù)據(jù)庫連接(database connectivity)和消息(messaging)等功能。

          雖然 Web服務(wù)器不支持事務(wù)處理或數(shù)據(jù)庫連接池,但它可以配置(employ)各種策略(strategies)來實現(xiàn)容錯性(fault tolerance)和可擴展性(scalability),例如負(fù)載平衡(load balancing),緩沖(caching)。集群特征(clustering—features)經(jīng)常被誤認(rèn)為僅僅是應(yīng)用程序服務(wù)器專有的特征。

          應(yīng)用程序服務(wù)器(The Application Server)
          根據(jù)我們的定義,作為應(yīng)用程序服務(wù)器, 它通過各種協(xié)議,可以包括HTTP,把商業(yè)邏輯暴露給(expose)客戶端應(yīng)用程序。Web服務(wù)器主要是處理向瀏覽器發(fā)送HTML以供瀏覽,而應(yīng)用程序 服務(wù)器提供訪問商業(yè)邏輯的途徑以供客戶端應(yīng)用程序使用。應(yīng)用程序使用此商業(yè)邏輯就象你調(diào)用對象的一個方法(或過程語言中的一個函數(shù))一樣。

          應(yīng)用程序服務(wù)器的客戶端(包含有圖形用戶界面(GUI)的)可能會運行在一臺PC、一個Web服務(wù)器或者甚至是其它的應(yīng)用程序服務(wù)器上。在應(yīng)用程序服務(wù) 器與其客戶端之間來回穿梭(traveling)的信息不僅僅局限于簡單的顯示標(biāo)記。相反,這種信息就是程序邏輯(program logic)。 正是由于這種邏輯取得了(takes)數(shù)據(jù)和方法調(diào)用(calls)的形式而不是靜態(tài)HTML,所以客戶端才可以隨心所欲的使用這種被暴露的商業(yè)邏輯。

          在大多數(shù)情形下,應(yīng)用程序服務(wù)器是通過組件(component)的應(yīng)用程序接口(API)把商業(yè)邏輯暴露(expose)(給客戶端應(yīng)用程序)的,例 如基于J2EE(Java 2 Platform, Enterprise Edition)應(yīng)用程序服務(wù)器的EJB(Enterprise JavaBean)組件模型。此外,應(yīng)用程序服務(wù)器可以管理自己的資源,例如看大門的工作(gate-keeping duties)包括安全(security),事務(wù)處理(transaction processing),資源池(resource pooling), 和消息(messaging)。就象Web服務(wù)器一樣,應(yīng)用程序服務(wù)器配置了多種可擴展(scalability)和容錯(fault tolerance)技術(shù)。

          一個例子
          例如,設(shè)想一個在線商店(網(wǎng)站)提供實時定價(real-time pricing)和有效性(availability)信息。這個站點(site)很可能會提供一個表單(form)讓你來選擇產(chǎn)品。當(dāng)你提交查詢 (query)后,網(wǎng)站會進行查找(lookup)并把結(jié)果內(nèi)嵌在HTML頁面中返回。網(wǎng)站可以有很多種方式來實現(xiàn)這種功能。我要介紹一個不使用應(yīng)用程序 服務(wù)器的情景和一個使用應(yīng)用程序服務(wù)器的情景。觀察一下這兩中情景的不同會有助于你了解應(yīng)用程序服務(wù)器的功能。

          情景 1:不帶應(yīng)用程序服務(wù)器的Web服務(wù)器

          在此種情景下,一個Web服務(wù)器獨立提供在線商店的功能。Web服務(wù)器獲 得你的請求(request),然后發(fā)送給服務(wù)器端(server-side)可以處理請求(request)的程序。此程序從數(shù)據(jù)庫或文本文件 (flat file,譯者注:flat file是指沒有特殊格式的非二進制的文件,如properties和XML文件等)中查找定價信息。一旦找到,服務(wù)器端(server-side)程序 把結(jié)果信息表示成(formulate)HTML形式,最后Web服務(wù)器把會它發(fā)送到你的Web瀏覽器。

          簡而言之,Web服務(wù)器只是簡 單的通過響應(yīng)(response)HTML頁面來處理HTTP請求(request)。

          情景2:帶應(yīng)用程序服務(wù)器的 Web服務(wù)器

          情景2和情景1相同的是Web服務(wù)器還是把響應(yīng)(response)的產(chǎn)生委托 (delegates)給腳本(譯者注:服務(wù)器端(server-side)程序)。然而,你可以把查找定價的商業(yè)邏輯(business logic)放到應(yīng)用程序服務(wù)器上。由于這種變化,此腳本只是簡單的調(diào)用應(yīng)用程序服務(wù)器的查找服務(wù)(lookup service),而不是已經(jīng)知道如何查找數(shù)據(jù)然后表示為(formulate)一個響應(yīng)(response)。 這時當(dāng)該腳本程序產(chǎn)生HTML響應(yīng)(response)時就可以使用該服務(wù)的返回結(jié)果了。

          在此情景中,應(yīng)用程序服務(wù)器提供 (serves)了用于查詢產(chǎn)品的定價信息的商業(yè)邏輯。(服務(wù)器的)這種功能(functionality)沒有指出有關(guān)顯示和客戶端如何使用此信息的細(xì) 節(jié),相反客戶端和應(yīng)用程序服務(wù)器只是來回傳送數(shù)據(jù)。當(dāng)有客戶端調(diào)用應(yīng)用程序服務(wù)器的查找服務(wù)(lookup service)時,此服務(wù)只是簡單的查找并返回結(jié)果給客戶端。

          通過從響應(yīng)產(chǎn)生(response-generating)HTML的 代碼中分離出來,在應(yīng)用程序之中該定價(查找)邏輯的可重用性更強了。其他的客戶端,例如收款機,也可以調(diào)用同樣的服務(wù)(service)來作為一個店員 給客戶結(jié)帳。相反,在情景1中的定價查找服務(wù)是不可重用的因為信息內(nèi)嵌在HTML頁中了。

          總而言之,在情景2的模型中,在Web服務(wù)器 通過回應(yīng)HTML頁面來處理HTTP請求(request),而應(yīng)用程序服務(wù)器則是通過處理定價和有效性(availability)請求 (request)來提供應(yīng)用程序邏輯的。

          警告(Caveats)
          現(xiàn)在,XML Web Services已經(jīng)使應(yīng)用程序服務(wù)器和Web服務(wù)器的界線混淆了。通過傳送一個XML有效載荷(payload)給服務(wù)器,Web服務(wù)器現(xiàn)在可以處理數(shù) 據(jù)和響應(yīng)(response)的能力與以前的應(yīng)用程序服務(wù)器同樣多了。

          另外,現(xiàn)在大多數(shù)應(yīng)用程序服務(wù)器也包含了Web服務(wù)器,這就意味 著可以把Web服務(wù)器當(dāng)作是應(yīng)用程序服務(wù)器的一個子集(subset)。雖然應(yīng)用程序服務(wù)器包含了Web服務(wù)器的功能,但是開發(fā)者很少把應(yīng)用程序服務(wù)器部 署(deploy)成這種功能(capacity)(譯者注:這種功能是指既有應(yīng)用程序服務(wù)器的功能又有Web服務(wù)器的功能)。相反,如果需要,他們通常 會把Web服務(wù)器獨立配置,和應(yīng)用程序服務(wù)器一前一后。這種功能的分離有助于提高性能(簡單的Web請求(request)就不會影響應(yīng)用程序服務(wù)器 了),分開配置(專門的Web服務(wù)器,集群(clustering)等等),而且給最佳產(chǎn)品的選取留有余地。


          posted @ 2010-05-14 10:19 小菜毛毛 閱讀(227) | 評論 (0)編輯 收藏

          HTTPS(Secure Hypertext Transfer Protocol)安全超文本傳輸協(xié)議
          它是一個安全通信通道,它基于HTTP開發(fā),用于在客戶計算機和服務(wù)器之間交換信息。它使用安全套接字層(SSL)進行信息交換,簡單來說它是HTTP的 安全版。
          它是由Netscape開發(fā)并內(nèi)置于其瀏覽器中,用于對數(shù)據(jù)進行壓縮和解壓操作,并返回網(wǎng)絡(luò)上傳送回的結(jié)果。HTTPS實際上應(yīng)用了Netscape的安 全全套接字層(SSL)作為HTTP應(yīng)用層的子層。(HTTPS使用端口443,而不是象HTTP那樣使用端口80來和TCP/IP進行通信。)SSL使 用40 位關(guān)鍵字作為RC4流加密算法,這對于商業(yè)信息的加密是合適的。HTTPS和SSL支持使用X.509數(shù)字認(rèn)證,如果需要的話用戶可以確認(rèn)發(fā)送者是誰。
          HTTPS和HTTP的區(qū)別:
          https協(xié)議需要到ca申請證書,一般免費證書很少,需要交費。
          http是超文本傳輸協(xié)議,信息是明文傳輸,https 則是具有安全性的ssl加密傳輸協(xié)議
          http和https使用的是完全不同的連接方式用的端口也不一樣,前者是80,后者是443。
          http的連接很簡單,是無狀態(tài)的
          HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議 要比http協(xié)議安全
          HTTPS解決的問題:
          1 . 信任主機的問題. 采用https 的server 必須從CA 申請一個用于證明服務(wù)器用途類型的證書. 改證書只有用于對應(yīng)的server 的時候,客戶度才信任次主機. 所以目前所有的銀行系統(tǒng)網(wǎng)站,關(guān)鍵部分應(yīng)用都是https 的. 客戶通過信任該證書,從而信任了該主機. 其實這樣做效率很低,但是銀行更側(cè)重安全. 這一點對我們沒有任何意義,我們的server ,采用的證書不管自己issue 還是從公眾的地方issue, 客戶端都是自己人,所以我們也就肯定信任該server.
          2 . 通訊過程中的數(shù)據(jù)的泄密和被竄改
          1. 一般意義上的https, 就是 server 有一個證書.
          a) 主要目的是保證server 就是他聲稱的server. 這個跟第一點一樣.
          b) 服務(wù)端和客戶端之間的所有通訊,都是加密的.
          i. 具體講,是客戶端產(chǎn)生一個對稱的密鑰,通過server 的證書來交換密鑰. 一般意義上的握手過程.
          ii. 加下來所有的信息往來就都是加密的. 第三方即使截獲,也沒有任何意義.因為他沒有密鑰. 當(dāng)然竄改也就沒有什么意義了.
          2. 少許對客戶端有要求的情況下,會要求客戶端也必須有一個證書.
          a) 這里客戶端證書,其實就類似表示個人信息的時候,除了用戶名/密碼, 還有一個CA 認(rèn)證過的身份. 應(yīng)為個人證書一般來說上別人無法模擬的,所有這樣能夠更深的確認(rèn)自己的身份.
          b) 目前少數(shù)個人銀行的專業(yè)版是這種做法,具體證書可能是拿U盤作為一個備份的載體.
          HTTPS 一定是繁瑣的.
          a) 本來簡單的http協(xié)議,一個get一個response. 由于https 要還密鑰和確認(rèn)加密算法的需要.單握手就需要6/7 個往返.
          i. 任何應(yīng)用中,過多的round trip 肯定影響性能.
          b) 接下來才是具體的http協(xié)議,每一次響應(yīng)或者請求, 都要求客戶端和服務(wù)端對會話的內(nèi)容做加密/解密.
          i. 盡管對稱加密/解密效率比較高,可是仍然要消耗過多的CPU,為此有專門的SSL 芯片. 如果CPU 信能比較低的話,肯定會降低性能,從而不能serve 更多的請求.
          ii. 加密后數(shù)據(jù)量的影響. 所以,才會出現(xiàn)那么多的安全認(rèn)證提示
          posted @ 2010-05-13 09:37 小菜毛毛 閱讀(288) | 評論 (0)編輯 收藏

          早早就聽說過開發(fā)方向的筆試面試都是以算法和數(shù)據(jù)結(jié)構(gòu)這些基礎(chǔ)為主,我自恃著那么一丁點項目經(jīng)驗,一直沒放在心上。

          連日下來的筆試徹底印證了師兄們的話,筆試基本不過。最可惜的是淘寶,筆試中發(fā)揮不錯終于能進一面,一開始聊家常聊框架聊開源技術(shù)還聊得不錯,突然 間,連續(xù)問了三個問題:

          1.多線程訪問hashtable和hashmap有什么不一樣?我只答出線程安全不一樣,具體怎么不一樣就有一句每一句了(回來google一 下,這種java基礎(chǔ)還真TM簡單,枉稱精通java了)

          2.平衡二叉樹查找算法的復(fù)雜度?再次雷響,隨便蒙了個歸并排序的復(fù)雜度給他。

          3.對于100W條數(shù)據(jù)的排序和查找有什么效率高的方式?完了,結(jié)結(jié)巴巴的說一通,最后自認(rèn)不會……

          原本以為技術(shù)面會比筆試好過的,回學(xué)校的路上我淚流滿面啊我。這些都不是RP問題了,鐵了心惡補數(shù)據(jù)結(jié)構(gòu)……

          Java線 程安全同步解決方案 

          1、 問題描述:

            如果一個資源或?qū)ο罂赡鼙欢鄠€線程同時訪問,它就是一個共享資源;例如 類的成員變量,包括類變量和實例變量,再比如對一個文件進行寫操作等。一般情況下,對共享資源的訪問需要考慮線程安全的問題。

            如果一個對象的完整生命周期只在一個線程內(nèi),則不需要考慮線程安全,例 如一個局部變量。下面為一個示例代碼:

          1. public class C1 {
          2. public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
          3. //其他代碼
          4. }

            假如在一個JSP中這樣的去調(diào)用:

          1. <a.jsp>:
          2. <%
          3. Java.util.Date date = C1.sdf.parse(“2003-4-15”);
          4. %>

            則這樣的代碼不是線程安全的。因為java.text.SimpleDateFormat 不是線程安全的,a.jsp中的代碼將會有若干個線程同時執(zhí)行,而都訪問的是同一個線程不安全的對象,這樣就不是一個線程安全的代碼。正確的寫法應(yīng)該如 下:

          1. <a.jsp>:
          2. <%
          3. java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
          4. Java.util.Date date = sdf.parse(“2003-4-15”);
          5. %>

          2、 原因分析:

            此時,sdf對象從創(chuàng)建到銷毀都位于一個方法中,相當(dāng)于一個局部變量,不是一個共享資源,因此則沒有線程不安全的問題。

          3、 解決方法或過程:

          1) 如果對象是immutable,則是線程安全的,例如:String,可以放心使用。
          2) 如果對象是線程安全的,則放心使用
          3) 有 條件線程安全,對于Vector和Hashtable一般情況下是線程安全的,但是對于某些特殊情況,需要通過額外的synchronized保證線程安 全。
          4) 使用synchronized關(guān)鍵字;

            對于上例中可以改寫jsp代碼,在sdf上進行同步,而不需要每次創(chuàng)建一個新的對象來保證線程安全,代碼如下:

          1. <%
          2. synchronized(C1.sdf){
          3. Java.util.Date date = C1.sdf.parse(“2003-4-15”);
          4. }
          5. %>

            這種寫法是在一個對象級別上進行同步,也就是說任何時候,對于這個對象,最多只能有一個線程在執(zhí)行同步方法。

            另外一種寫法是在Class級別上進行同步,寫法如下:

          1. public class C1 {
          2. public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
          3. public void method(){
          4. synchronized(C1.class){
          5. //synchronized code
          6. }
          7. }
          8. }

            這種寫法表示無論C1有多少個實例,在任何一個時間點,最多只能有一個線程和一個實例進入同步塊中。這種同步會比較大的影響性能。

            5) 有些對象不能在多線程間共享,則只能在方法內(nèi)部使用,或者只在一個線程內(nèi)部使用。

          synchronized詳解

          Java對多線程的支持與同步機制深受大家的喜愛,似乎看起來使用了synchronized關(guān)鍵字就可以輕松地解決多線程共享數(shù)據(jù)同步問題。到底如何?――還得對synchronized關(guān)鍵字的作用進行深入了解才可定論。

          總的說來,synchronized關(guān)鍵字可以作為函數(shù)的修飾符,也可作為函數(shù)內(nèi)的語句,也就是平時說的同步方法和同步語句塊。如果再細(xì)的分類,synchronized可作用于instance變量、object reference(對象引用)、static函數(shù)和class literals(類名稱字面常量)身上。

          在進一步闡述之前,我們需要明確幾點:

          A.無論synchronized關(guān)鍵字加在方法上還是對象上,它取得的鎖都是對象,而不是把一段代碼或函數(shù)當(dāng)作鎖――而且同步方法很可能還會被其他線程的對象訪問。

          B.每個對象只有一個鎖(lock)與之相關(guān)聯(lián)。

          C.實現(xiàn)同步是要很大的系統(tǒng)開銷作為代價的,甚至可能 造成死鎖,所以盡量避免無謂的同步控制。

          接著來討論synchronized

          用到不同地方對代碼產(chǎn)生的影響:

          假設(shè)P1P2是同一個類的不同對象,這個類中定義了以下幾種情況的同步塊或同步方法,P1、P2就都可以調(diào)用它們。

          1. synchronized當(dāng)作函數(shù)修飾符時,示例代碼如下:

          Public synchronized void methodAAA()

          {

          //….

          }

          這也就是同步方法,那這時synchronized鎖定的是哪個對象呢?它鎖定的是調(diào)用這個同步方法對象。也就是說,當(dāng)一個對象P1在不 同的線程中執(zhí)行這個同步方法時,它們之間會形成互斥,達到同步的效果。但是這個對象所屬的Class所 產(chǎn)生的另一對象P2卻可以任意調(diào)用這個被加了synchronized關(guān)鍵字的方法。

          上邊的示例代碼等同于如下代碼:

          public void methodAAA()

          {

          synchronized (this)      // (1)

          {

                 //…..

          }

          }

           (1)處 的this指的是什么呢?它指的就是調(diào)用這個方法的對象,如P1??梢? 同步方法實質(zhì)是將synchronized作用于object reference。――那個拿到了P1對象 鎖的線程,才可以調(diào)用P1的同步方法,而對P2而 言,P1這個鎖與它毫不相干,程序也可能在這種情形下擺脫同步機制的控制,造成數(shù)據(jù)混亂:(

          2.同步塊,示例代碼如下:

                     public void method3(SomeObject so)

                        {

                               synchronized(so)

          {

                 //…..

          }

          }

          這時,鎖就是so這個對象,誰拿到這個鎖誰就可以運行它所控制的那段代碼。當(dāng)有一個明確的對象作為鎖時,就可以這樣寫程序,但當(dāng)沒有明確的對象作為 鎖,只是想讓一段代碼同步時,可以創(chuàng)建一個特殊的instance變量(它得是一個對象)來充當(dāng)鎖:

          class Foo implements Runnable

          {

                 private byte[] lock = new byte[0]; // 特殊的instance變量

              Public void methodA()

          {

                 synchronized(lock) { //… }

          }

          //…..

          }

          注:零長度的byte數(shù) 組對象創(chuàng)建起來將比任何對象都經(jīng)濟――查看編譯后的字節(jié)碼:生成零長度的byte[]對 象只需3條操作碼,而Object lock = new Object()則 需要7行操作碼。

          3.將synchronized作用于static 函數(shù),示例代碼如下:

                Class Foo

          {

          public synchronized static void methodAAA()   // 同步的static 函數(shù)

          {

          //….

          }

          public void methodBBB()

          {

                 synchronized(Foo.class)   // class literal(類名稱字面常量)

          }

                 }

             代碼中的methodBBB()方法是把class literal作為鎖的情況,它和同步的static函 數(shù)產(chǎn)生的效果是一樣的,取得的鎖很特別,是當(dāng)前調(diào)用這個方法的對象所屬的類(Class, 而不再是由這個Class產(chǎn)生的某個具體對象了)。

          記得在《Effective Java》一書中看到過將 Foo.class P1.getClass()用于作同步鎖還不一樣,不能用P1.getClass()來達到鎖這個Class的目的。P1指的是由Foo類產(chǎn)生的對象。

          可以推斷:如果一個類中定義了一個synchronizedstatic函數(shù)A,也定 義了一個synchronized instance函數(shù)B,那么這個類的同一對象Obj在多線程中分別訪問AB兩個方法時,不會構(gòu)成同步,因為它們的鎖都不一樣。A方法的鎖 是Obj這個對象,而B的鎖是Obj所屬的那個Class。

          小結(jié)如下:

          搞清楚synchronized鎖定的是哪個對象,就能幫助我們設(shè)計更安全的多線程程序。

          還有一些技巧可以讓我們對共享資源的同步訪問更加安全:

          1. 定義private instance變量+它的 get方法,而不要定義public/protectedinstance變量。如果將變量定義為public,對象在外界可以繞過同步方法的控制而 直接取得它,并改動它。這也是JavaBean的標(biāo)準(zhǔn)實現(xiàn)方式之一。

          2. 如果instance變量是一個對象,如數(shù)組或ArrayList什么的,那上述方法仍然不安全, 因為當(dāng)外界對象通過get方法拿到這個instance對象的引用后,又將其指向另一個對象,那么這個private變量也就變了,豈不是很危險。這個時候就需要將get方法 也加上synchronized同步,并且,只返回這個private對象的clone()――這樣,調(diào)用端得到的就是對象副本的引用了。



          posted @ 2010-05-11 09:49 小菜毛毛 閱讀(918) | 評論 (0)編輯 收藏

          字符,字節(jié)和編碼

          轉(zhuǎn)載自:http://www.regexlab.com/zh/encoding.htm

          級別:中級

          摘要:本文介紹了字符與編碼的發(fā)展過程,相關(guān)概念的正確理解。舉例說明了一些實際應(yīng)用中,編碼的實現(xiàn)方法。然后,本文 講述了通常對字符與編碼的幾種誤解,由于這些誤解而導(dǎo)致亂碼產(chǎn)生的原因,以及消除亂碼的辦法。本文的內(nèi)容涵蓋了“中文問題”,“亂碼問題”。

          掌握編碼問題的關(guān)鍵是正確地理解相關(guān)概念,編碼所涉及的技術(shù)其實是很簡單的。因此,閱讀本文時需要慢讀多想,多思考。

          引言

          “字符與編碼”是一個被經(jīng)常討論的話題。即使這樣,時常出現(xiàn)的亂碼仍然困擾著大家。雖然我們有很多的辦法可以用來消除亂 碼,但我們并不一定理解這些辦法的內(nèi)在原理。而有的亂碼產(chǎn)生的原因,實際上由于底層代碼本身有問題所導(dǎo)致的。因此,不僅是初學(xué)者會對字符編碼感到模糊,有 的底層開發(fā)人員同樣對字符編碼缺乏準(zhǔn)確的理解。

          回頁首

          1. 編碼問題的由來,相關(guān)概念的理解

          1.1 字符與編碼的發(fā)展

          從計算機對多國語言的支持角度看,大致可以分為三個階段:

          系統(tǒng)內(nèi)碼 說明 系統(tǒng)
          階段一 ASCII 計算機剛開始只支持英語,其它語言不能夠在計算機上存儲和顯示。 英文 DOS
          階段二 ANSI編碼
          (本地化)
          為使計算機支持更多語言,通常使用 0x80~0xFF 范圍的 2 個字節(jié)來表示 1 個字符。比如:漢字 '中' 在中文操作系統(tǒng)中,使用 [0xD6,0xD0] 這兩個字節(jié)存儲。

          不同的國家和地區(qū)制定了不同的標(biāo)準(zhǔn),由此產(chǎn)生了 GB2312, BIG5, JIS 等各自的編碼標(biāo)準(zhǔn)。這些使用 2 個字節(jié)來代表一個字符的各種漢字延伸編碼方式,稱為 ANSI 編碼。在簡體中文系統(tǒng)下,ANSI 編碼代表 GB2312 編碼,在日文操作系統(tǒng)下,ANSI 編碼代表 JIS 編碼。

          不同 ANSI 編碼之間互不兼容,當(dāng)信息在國際間交流時,無法將屬于兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。
          中文 DOS,中文 Windows 95/98,日文 Windows 95/98
          階段三 UNICODE
          (國際化)
          為了使國際間信息交流更加方便,國際組織制定了 UNICODE 字符集, 為各種語言中的每一個字符設(shè)定了統(tǒng)一并且唯一的數(shù)字編號,以滿足跨語言、跨平臺進行文本轉(zhuǎn)換、處理的要求。 Windows NT/2000/XP,Linux,Java

          字符串在內(nèi)存中的存放方法:

          在 ASCII 階段,單字節(jié)字符串使用一個字節(jié)存放一個字符(SBCS)。比如,"Bob123" 在內(nèi)存中為:

          42 6F 62 31 32 33 00
          B o b 1 2 3 "0

          在使用 ANSI 編碼支持多種語言階段,每個字符使用一個字節(jié)或多個字節(jié)來表示(MBCS),因此,這種方式存放的字符也被稱作多字節(jié)字符。比如,"中文 123" 在中文 Windows 95 內(nèi)存中為7個字節(jié),每個漢字占2個字節(jié),每個英文和數(shù)字字符占1個字節(jié):

          D6 D0 CE C4 31 32 33 00
          1 2 3 "0

          在 UNICODE 被采用之后,計算機存放字符串時,改為存放每個字符在 UNICODE 字符集中的序號。目前計算機一般使用 2 個字節(jié)(16 位)來存放一個序號(DBCS),因此,這種方式存放的字符也被稱作寬字節(jié)字符。 比如,字符串 "中文123" 在 Windows 2000 下,內(nèi)存中實際存放的是 5 個序號:

          2D 4E 87 65 31 00 32 00 33 00 00 00      ← 在 x86 CPU 中,低字節(jié)在前
          1 2 3 "0

          一共占 10 個字節(jié)。

          回頁首

          1.2 字符,字節(jié),字符串

          理解編碼的關(guān)鍵,是要把字符的概念和字節(jié)的概念理解準(zhǔn)確。這兩個概念容易混淆,我們在此做一下區(qū)分:

          概念描述 舉例
          字符 人們使用的記號,抽象意義上的一個符號。 '1', '中', 'a', '$', '¥', ……
          字節(jié) 計算機中存儲數(shù)據(jù)的單元,一個8位的二進制數(shù),是一個很具體的存儲空間。 0x01, 0x45, 0xFA, ……
          ANSI
          字符串
          在內(nèi)存中,如果“字符”是以 ANSI 編碼形式存在的,一個字符 可能使用一個字節(jié)或多個字節(jié)來表示,那么我們稱這種字符串為 ANSI 字符串或者多字節(jié)字符串。 "中文123"
          (占7字節(jié))
          UNICODE
          字符串
          在內(nèi)存中,如果“字符”是以在 UNICODE 中的序號存在的,那么我們稱這種字符串為 UNICODE 字符串或者寬字節(jié)字符串。 L"中文123"
          (占10字節(jié))

          由于不同 ANSI 編碼所規(guī)定的標(biāo)準(zhǔn)是不相同的,因此,對于一個給定的多字節(jié)字符串,我們必須知道它采用 的是哪一種編碼規(guī)則,才能夠知道它包含了哪些“字符”。而對于 UNICODE 字符串來說,不管在什么環(huán)境下,它所代表的“字符”內(nèi)容總 是不變的。

          回頁首

          1.3 字符集與編碼

          各個國家和地區(qū)所制定的不同 ANSI 編碼標(biāo)準(zhǔn)中,都只規(guī)定了各自語言所需的“字符”。比如:漢字標(biāo)準(zhǔn)(GB2312)中沒有規(guī)定韓國語字符怎樣存儲。這些 ANSI 編碼標(biāo)準(zhǔn)所規(guī)定的內(nèi)容包含兩層含義:

          1. 使用哪些字符。也就是說哪些漢字,字母和符號會被收入標(biāo)準(zhǔn)中。所包含“字符”的集合就叫做“字符集”。
          2. 規(guī)定每個“字符”分別用一個字節(jié)還是多個字節(jié)存儲,用哪些字節(jié)來存儲,這個規(guī)定就叫做“編碼”。

          各個國家和地區(qū)在制定編碼標(biāo)準(zhǔn)的時候,“字符的集合”和“編碼”一般都是同時制定的。因此,平常我們所說的“字符集”,比 如:GB2312, GBK, JIS 等,除了有“字符的集合”這層含義外,同時也包含了“編碼”的含義。

          UNICODE 字符集”包含了各種語言中使用到的所有“字符”。用來給 UNICODE 字符集編碼的標(biāo)準(zhǔn)有很多種,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。

          回頁首

          1.4 常用的編碼簡介

          簡單介紹一下常用的編碼規(guī)則,為后邊的章節(jié)做一個準(zhǔn)備。在這里,我們根據(jù)編碼規(guī)則的特點,把所有的編碼分成三類:

          分類 編碼標(biāo)準(zhǔn) 說明
          單字節(jié)字符編碼 ISO-8859-1 最簡單的編碼規(guī)則,每一個字節(jié)直接作為一個 UNICODE 字符。比如,[0xD6, 0xD0] 這兩個字節(jié),通過 iso-8859-1 轉(zhuǎn)化為字符串時,將直接得到 [0x00D6, 0x00D0] 兩個 UNICODE 字符,即 "ÖÐ"。

          反之,將 UNICODE 字符串通過 iso-8859-1 轉(zhuǎn)化為字節(jié)串時,只能正常轉(zhuǎn)化 0~255 范圍的字符。
          ANSI 編碼 GB2312,
          BIG5,
          Shift_JIS,
          ISO-8859-2 ……
          把 UNICODE 字符串通過 ANSI 編碼轉(zhuǎn)化為“字節(jié)串”時,根據(jù)各自編碼的規(guī)定,一個 UNICODE 字符可能轉(zhuǎn)化成一個字節(jié)或多個字節(jié)。

          反之,將字節(jié)串轉(zhuǎn)化成字符串時,也可能多個字節(jié)轉(zhuǎn)化成一個字符。比如,[0xD6, 0xD0] 這兩個字節(jié),通過 GB2312 轉(zhuǎn)化為字符串時,將得到 [0x4E2D] 一個字符,即 '中' 字。

          “ANSI 編碼”的特點:
          1. 這些“ANSI 編碼標(biāo)準(zhǔn)”都只能處理各自語言范圍之內(nèi)的 UNICODE 字符。
          2. “UNICODE 字符”與“轉(zhuǎn)換出來的字節(jié)”之間的關(guān)系是人為規(guī)定的。
          UNICODE 編碼 UTF-8,
          UTF-16, UnicodeBig ……
          與“ANSI 編碼”類似的,把字符串通過 UNICODE 編碼轉(zhuǎn)化成“字節(jié)串”時,一個 UNICODE 字符可能轉(zhuǎn)化成一個字節(jié)或多個字節(jié)。

          與“ANSI 編碼”不同的是:
          1. 這些“UNICODE 編碼”能夠處理所有的 UNICODE 字符。
          2. “UNICODE 字符”與“轉(zhuǎn)換出來的字節(jié)”之間是可以通過計算得到的。

          我們實際上沒有必要去深究每一種編碼具體把某一個字符編碼成了哪幾個字節(jié),我們只需要知道“編碼”的概念就是把“字符”轉(zhuǎn) 化成“字節(jié)”就可以了。對于“UNICODE 編碼”,由于它們是可以通過計算得到的,因此,在特殊的場合,我們可以去了解某一種“UNICODE 編碼”是怎樣的規(guī)則。

          回頁首

          2. 字符與編碼在程序中的實現(xiàn)

          2.1 程序中的字符與字節(jié)

          在 C++ 和 Java 中,用來代表“字符”和“字節(jié)”的數(shù)據(jù)類型,以及進行編碼的方法:

          類型或操作 C++ Java
          字符 wchar_t char
          字節(jié) char byte
          ANSI 字符串 char[] byte[]
          UNICODE 字符串 wchar_t[] String
          字節(jié)串→字符串 mbstowcs(), MultiByteToWideChar() string = new String(bytes, "encoding")
          字符串→字節(jié)串 wcstombs(), WideCharToMultiByte() bytes = string.getBytes("encoding")

          以上需要注意幾點:

          1. Java 中的 char 代表一個“UNICODE 字符(寬字節(jié)字符)”,而 C++ 中的 char 代表一個字節(jié)。
          2. MultiByteToWideChar() 和 WideCharToMultiByte() 是 Windows API 函數(shù)。

          回頁首

          2.2 C++ 中相關(guān)實現(xiàn)方法

          聲明一段字符串常量:

          // ANSI 字符串,內(nèi)容長度 7 字節(jié)
          char
               sz[20] = "中文123";

          // UNICODE 字符串,內(nèi)容長度 5 個 wchar_t(10 字節(jié))
          wchar_t wsz[20] = L""x4E2D"x6587"x0031"x0032"x0033";

          UNICODE 字符串的 I/O 操作,字符與字節(jié)的轉(zhuǎn)換操作:

          // 運行時設(shè)定當(dāng)前 ANSI 編碼,VC 格式
          setlocale(LC_ALL, ".936");

          // GCC 中格式
          setlocale(LC_ALL, "zh_CN.GBK");

          // Visual C++ 中使用小寫 %s,按照 setlocale 指定編碼輸出到文件
          // GCC 中使用大寫 %S

          fwprintf(fp, L"%s"n", wsz);

          // 把 UNICODE 字符串按照 setlocale 指定的編碼轉(zhuǎn)換成字節(jié)
          wcstombs(sz, wsz, 20);
          // 把字節(jié)串按照 setlocale 指定的編碼轉(zhuǎn)換成 UNICODE 字符串
          mbstowcs(wsz, sz, 20);

          在 Visual C++ 中,UNICODE 字符串常量有更簡單的表示方法。如果源程序的編碼與當(dāng)前默認(rèn) ANSI 編碼不符,則需要使用 #pragma setlocale,告訴編譯器源程序使用的編碼:

          // 如果源程序的編碼與當(dāng)前默認(rèn) ANSI 編碼不一致,
          // 則需要此行,編譯時用來指明當(dāng)前源程序使用的編碼

          #pragma setlocale
          (".936")

          // UNICODE 字符串常量,內(nèi)容長度 10 字節(jié)
          wchar_t wsz[20] = L"中文123";

          以上需要注意 #pragma setlocale 與 setlocale(LC_ALL, "") 的作用是不同的,#pragma setlocale 在編譯時起作用,setlocale() 在運行時起作用。

          回頁首

          2.3 Java 中相關(guān)實現(xiàn)方法

          字符串類 String 中的內(nèi)容是 UNICODE 字符串:

          // Java 代碼,直接寫中文
          String
          string = "中文123";

          // 得到長度為 5,因為是 5 個字符
          System.out.println(string.length());

          字符串 I/O 操作,字符與字節(jié)轉(zhuǎn)換操作。在 Java 包 java.io.* 中,以“Stream”結(jié)尾的類一般是用來操作“字節(jié)串”的類,以“Reader”,“Writer”結(jié)尾的類一般是用來操作“字符串”的類。

          // 字符串與字節(jié)串間相互轉(zhuǎn)化

          // 按照 GB2312 得到字節(jié)(得到多字節(jié)字符串)

          byte
          [] bytes = string.getBytes("GB2312");

          // 從字節(jié)按照 GB2312 得到 UNICODE 字符串
          string = new String(bytes, "GB2312");

          // 要將 String 按照某種編碼寫入文本文件,有兩種方法:

          // 第一種辦法:用 Stream 類寫入已經(jīng)按照指定編碼轉(zhuǎn)化好的字節(jié)串

          OutputStream os = new FileOutputStream("1.txt");
          os.write(bytes);
          os.close();

          // 第二種辦法:構(gòu)造指定編碼的 Writer 來寫入字符串
          Writer ow = new OutputStreamWriter(new FileOutputStream("2.txt"), "GB2312");
          ow.write(string);
          ow.close();

          /* 最后得到的 1.txt 和 2.txt 都是 7 個字節(jié) */

          如果 java 的源程序編碼與當(dāng)前默認(rèn) ANSI 編碼不符,則在編譯的時候,需要指明一下源程序的編碼。比如:

          E:">javac -encoding BIG5 Hello.java

          以上需要注意區(qū)分源程序的編碼與 I/O 操作的編碼,前者是在編譯時起作用,后者是在運行時起作用。

          回頁首

          3. 幾種誤解,以及亂碼產(chǎn)生的原因和解決辦法

          3.1 容易產(chǎn)生的誤解
          對編碼的誤解
          誤解一 在將“字節(jié)串”轉(zhuǎn)化成“UNICODE 字符串”時,比如在讀取文本文件時,或者通過網(wǎng)絡(luò)傳輸文本時,容易將“字節(jié)串”簡單地作為單字節(jié)字符串,采用每“一個字節(jié)”就是“一個字 符”的方法進行轉(zhuǎn)化。

          而實際上,在非英文的環(huán)境中,應(yīng)該將“字節(jié)串”作為 ANSI 字符串,采用適當(dāng)?shù)木幋a來得到 UNICODE 字符串,有可能“多個字節(jié)”才能得到“一個字符”。

          通常,一直在英文環(huán)境下做開發(fā)的程序員們,容易有這種誤解。
          誤解二 在 DOS,Windows 98 等非 UNICODE 環(huán)境下,字符串都是以 ANSI 編碼的字節(jié)形式存在的。這種以字節(jié)形式存在的字符串,必須知道是哪種編碼才能被正確地使用。這使我們形成了一個慣性思維:“字符串的編碼”。

          當(dāng) UNICODE 被支持后,Java 中的 String 是以字符的“序號”來存儲的,不是以“某種編碼的字節(jié)”來存儲的,因此已經(jīng)不存在“字符串的編碼”這個概念了。只有在“字符串”與“字節(jié)串”轉(zhuǎn)化時,或 者,將一個“字節(jié)串”當(dāng)成一個 ANSI 字符串時,才有編碼的概念。

          不少的人都有這個誤解。

          第一種誤解,往往是導(dǎo)致亂碼產(chǎn)生的原因。第二種誤解,往往導(dǎo)致本來容易糾正的亂碼問題變得更復(fù)雜。

          在這里,我們可以看到,其中所講的“誤解一”,即采用每“一個字節(jié)”就是“一個字符”的轉(zhuǎn)化方法,實際上也就等同于采用 iso-8859-1 進行轉(zhuǎn)化。因此,我們常常使用 bytes = string.getBytes("iso-8859-1") 來進行逆向操作,得到原始的“字節(jié)串”。然后再使用正確的 ANSI 編碼,比如 string = new String(bytes, "GB2312"),來得到正確的“UNICODE 字符串”。

          回頁首

          3.2 非 UNICODE 程序在不同語言環(huán)境間移植時的亂碼

          非 UNICODE 程序中的字符串,都是以某種 ANSI 編碼形式存在的。如果程序運行時的語言環(huán)境與開發(fā)時的語言環(huán)境不同,將會導(dǎo)致 ANSI 字符串的顯示失敗。

          比如,在日文環(huán)境下開發(fā)的非 UNICODE 的日文程序界面,拿到中文環(huán)境下運行時,界面上將顯示亂碼。如果這個日文程序界面改為采用 UNICODE 來記錄字符串,那么當(dāng)在中文環(huán)境下運行時,界面上將可以顯示正常的日文。

          由于客觀原因,有時候我們必須在中文操作系統(tǒng)下運行非 UNICODE 的日文軟件,這時我們可以采用一些工具,比如,南極星,AppLocale 等,暫時的模擬不同的語言環(huán)境。

          回頁首

          3.3 網(wǎng)頁提交字符串

          當(dāng)頁面中的表單提交字符串時,首先把字符串按照當(dāng)前頁面的編碼,轉(zhuǎn)化成字節(jié)串。然后再將每個字節(jié)轉(zhuǎn)化成 "%XX" 的格式提交到 Web 服務(wù)器。比如,一個編碼為 GB2312 的頁面,提交 "中" 這個字符串時,提交給服務(wù)器的內(nèi)容為 "%D6%D0"。

          在服務(wù)器端,Web 服務(wù)器把收到的 "%D6%D0" 轉(zhuǎn)化成 [0xD6, 0xD0] 兩個字節(jié),然后再根據(jù) GB2312 編碼規(guī)則得到 "中" 字。

          在 Tomcat 服務(wù)器中,request.getParameter() 得到亂碼時,常常是因為前面提到的“誤解一”造成的。默認(rèn)情況下,當(dāng)提交 "%D6%D0" 給 Tomcat 服務(wù)器時,request.getParameter() 將返回 [0x00D6, 0x00D0] 兩個 UNICODE 字符,而不是返回一個 "中" 字符。因此,我們需要使用 bytes = string.getBytes("iso-8859-1") 得到原始的字節(jié)串,再用 string = new String(bytes, "GB2312") 重新得到正確的字符串 "中"。

          回頁首

          3.4 從數(shù)據(jù)庫讀取字符串

          通過數(shù)據(jù)庫客戶端(比如 ODBC 或 JDBC)從數(shù)據(jù)庫服務(wù)器中讀取字符串時,客戶端需要從服務(wù)器獲知所使用的 ANSI 編碼。當(dāng)數(shù)據(jù)庫服務(wù)器發(fā)送字節(jié)流給客戶端時,客戶端負(fù)責(zé)將字節(jié)流按照正確的編碼轉(zhuǎn)化成 UNICODE 字符串。

          如果從數(shù)據(jù)庫讀取字符串時得到亂碼,而數(shù)據(jù)庫中存放的數(shù)據(jù)又是正確的,那么往往還是因為前面提到的“誤解一”造成的。解決 的辦法還是通過 string = new String( string.getBytes("iso-8859-1"), "GB2312") 的方法,重新得到原始的字節(jié)串,再重新使用正確的編碼轉(zhuǎn)化成字符串。

          回頁首

          3.5 電子郵件中的字符串

          當(dāng)一段 Text 或者 HTML 通過電子郵件傳送時,發(fā)送的內(nèi)容首先通過一種指定的字符編碼轉(zhuǎn)化成“字 節(jié)串”,然后再把“字節(jié)串”通過一種指定的傳輸編碼(Content-Transfer-Encoding)進行轉(zhuǎn)化得到另一串“字節(jié) 串”。比如,打開一封電子郵件源代碼,可以看到類似的內(nèi)容:

          Content-Type: text/plain;
                  charset="gb2312"
          Content-Transfer-Encoding: base64

          sbG+qcrQuqO17cf4yee74bGjz9W7+b3wudzA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0NDEDQoNCg==

          最常用的 Content-Transfer-Encoding 有 Base64 和 Quoted-Printable 兩種。在對二進制文件或者中文文本進行轉(zhuǎn)化時,Base64 得到的“字節(jié)串”比 Quoted-Printable 更短。在對英文文本進行轉(zhuǎn)化時,Quoted-Printable 得到的“字節(jié)串”比 Base64 更短。

          郵件的標(biāo)題,用了一種更簡短的格式來標(biāo)注“字符編碼”和“傳輸編碼”。比如,標(biāo)題內(nèi)容為 "中",則在郵件源代碼中表示為:

          // 正確的標(biāo)題格式
          Subject: =?GB2312?B?1tA=?=

          其中,

          • 第一個“=?”與“?”中間的部分指定了字符編碼,在這個例子中指定的是 GB2312。
          • “?”與“?”中間的“B”代表 Base64。如果是“Q”則代表 Quoted-Printable。
          • 最后“?”與“?=”之間的部分,就是經(jīng)過 GB2312 轉(zhuǎn)化成字節(jié)串,再經(jīng)過 Base64 轉(zhuǎn)化后的標(biāo)題內(nèi)容。

          如果“傳輸編碼”改為 Quoted-Printable,同樣,如果標(biāo)題內(nèi)容為 "中":

          // 正確的標(biāo)題格式
          Subject: =?GB2312?Q?=D6=D0?=

          如果閱讀郵件時出現(xiàn)亂碼,一般是因為“字符編碼”或“傳輸編碼”指定有誤,或者是沒有指定。比如,有的發(fā)郵件組件在發(fā)送郵 件時,標(biāo)題 "中":

          // 錯誤的標(biāo)題格式
          Subject: =?ISO-8859-1?Q?=D6=D0?=

          這樣的表示,實際上是明確指明了標(biāo)題為 [0x00D6, 0x00D0],即 "ÖÐ",而不是 "中"。

          回頁首

          4. 幾種錯誤理解的糾正

          誤解:“ISO-8859-1 是國際編碼?”

          非也。iso-8859-1 只是單字節(jié)字符集中最簡單的一種,也就是“字節(jié)編號”與“UNICODE 字符編號”一致的那種編碼規(guī)則。當(dāng)我們要把一個“字節(jié)串”轉(zhuǎn)化成“字符串”,而又不知道它是哪一種 ANSI 編碼時,先暫時地把“每一個字節(jié)”作為“一個字符”進行轉(zhuǎn)化,不會造成信息丟失。然后再使用 bytes = string.getBytes("iso-8859-1") 的方法可恢復(fù)到原始的字節(jié)串。

          誤解:“Java 中,怎樣知道某個字符串的內(nèi)碼?”

          Java 中,字符串類 java.lang.String 處理的是 UNICODE 字符串,不是 ANSI 字符串。我們只需要把字符串作為“抽象的符號的串”來看待。因此不存在字符串的內(nèi)碼的問題。

          posted @ 2010-04-30 11:15 小菜毛毛 閱讀(368) | 評論 (0)編輯 收藏

          想寫個struts 2.0+tiles模版玩玩,沒有想到找資料還麻煩,于是自己把通宵弄好的過程記下來,以供大家有急需,不足的地方歡迎交流。

          1.在WEB-INF/lib下加入所需的jar包 

              commons-digester-1.6.jar,

              tiles-core-2.0-20070207.130156-4.jar,
              tiles-api-2.0-20070207.130156-4.jar,
              struts2-tiles-plugin-2.0.6.jar,
          struts2-core-2.0.6.jar
          xwork-2.0.1.jar,
          2. 以下內(nèi)容添加到web.xml
           <context-param>
                 <param-name>org.apache.tiles.CONTAINER_FACTORY</param-name>
                 <param-value>
                     org.apache.struts2.tiles.StrutsTilesContainerFactory
                 </param-value>
              </context-param>
             
              <context-param>
                 <param-name>   org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
                 </param-name>
                 <param-value>/WEB-INF/tiles.xml</param-value>
              </context-param>
           
              <listener>
                 <listener-class>
                     org.apache.struts2.tiles.StrutsTilesListener
                 </listener-class>
              </listener>
          3.在WEB-INF下添加和tiles.tld和tiles.xml文件,其中tiles.tld內(nèi)容為tiles-core- 2.0-20070207.130156-4.jar包中META_INF/tiles-core.tld的內(nèi)容。
          tiles.xml內(nèi)容:
          <?xml version="1.0" encoding="GB2312" ?>
          <!DOCTYPE tiles-definitions PUBLIC
                 "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
                 "http://jakarta.apache.org/struts/dtds/tiles-config.dtd">
          <tiles-definitions>
              <definition name="myapp.homepage" template="layout.jsp">
                 <put name="title" value="Tiles tutorial homepage" />
                 <put name="header" value="/tiles/header.jsp" />
                 <put name="menu" value="/tiles/menu.jsp" />
                 <put name="body" value="/tiles/cBody.jsp" />
                 <put name="footer" value="/tiles/footer.jsp" />
              </definition>
          </tiles-definitions>
             
          4.struts.xml 為:
          <!DOCTYPE struts PUBLIC  
                  "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
                  "http://struts.apache.org/dtds/struts-2.0.dtd">
          <struts>
              <package name="default" extends="tiles-default">
                 <action name="go" class="com.action.MyAction">
                     <!--result name="success">/next.jsp</result-->
                     <result name="success" type="tiles">myapp.homepage</result>
                 </action>
                 </package>
          </struts>
          紅色部分根據(jù)自己項目 定。注意extends="tiles-default"
          5創(chuàng)建layout.jsp
          <%@ page contentType="text/html; charset=UTF-8"%>
          <%@ taglib uri="WEB-INF/tiles.tld " prefix="tiles"%>
          <html>
              <head>
                 <title></title>
              </head>
              <body>
                 <table width="768px" height="800px" border="2" align="center">
                
                     <tr>
                        <td colspan="2" align="center" valign="top" width="768px" height="100px" bgcolor="#80ff80">
                            <tiles:insertAttribute name="header" />
                        </td>
                     </tr>
                     <tr>
                        <td align="center" width="150px" height="800px" bgcolor="#00ff00">
                            <tiles:insertAttribute name="menu" />
                        </td>
                        <td align="right" width="618px" height="800px" bgcolor="#ff80c0">
                            <tiles:insertAttribute name="body" />
                        </td>
                     </tr>
                     <tr>
                        <td colspan="2" bgcolor="#00ff40" height="100px">
                            <tiles:insertAttribute name="footer" />
                        </td>
                     </tr>
                 </table>
              </body>
          </html>
           
          6.根據(jù)
          <put name="title" value="Tiles tutorial homepage" />
                 <put name="header" value="/tiles/header.jsp" />
                 <put name="menu" value="/tiles/menu.jsp" />
                 <put name="body" value="/tiles/cBody.jsp" />
                 <put name="footer" value="/tiles/footer.jsp" />
          WebRoot下創(chuàng) 建tiles目錄和相應(yīng)jsp文件
          7.OK了!下載源代碼到我的CSDN資源http://download.csdn.net/user/haoxing272
          null
          posted @ 2010-04-26 15:12 小菜毛毛 閱讀(4708) | 評論 (1)編輯 收藏

          獲取 MIME:HttpContext.Current.Request.Files[fileKey].ContentLength

          MIME類型就是設(shè)定某種擴展名 的文件用一種應(yīng)用程序來打開的方式類型,當(dāng)該擴展名文件被訪問的時候,瀏覽器會自動使用指定應(yīng)用程序來打開。多用于指定一些客戶端自定義的文件名,以及一些媒體文件打開方式。

          下面列出常用的文件對應(yīng)的MIME類型:

          Mime- Types(mime類型) Dateiendung(擴 展名) Bedeutung
          application/msexcel *.xls *.xla Microsoft Excel Dateien
          application/mshelp *.hlp *.chm Microsoft Windows Hilfe Dateien
          application/mspowerpoint *.ppt *.ppz *.pps *.pot Microsoft Powerpoint Dateien
          application/msword *.doc *.dot Microsoft Word Dateien

          application/octet-stream

          *.exe exe
          application/pdf *.pdf Adobe PDF-Dateien
          application/post****** *.ai *.eps *.ps Adobe Post******-Dateien
          application/rtf *.rtf Microsoft RTF-Dateien
          application/x-httpd-php *.php *.phtml PHP-Dateien
               
          application/x-java****** *.js serverseitige Java******-Dateien
          application/x-shockwave-flash *.swf *.cab Flash Shockwave-Dateien
          application/zip *.zip ZIP-Archivdateien
          audio/basic *.au *.snd Sound-Dateien
          audio/mpeg *.mp3 MPEG-Dateien
          audio/x-midi *.mid *.midi MIDI-Dateien
          audio/x-mpeg *.mp2 MPEG-Dateien
          audio/x-wav *.wav Wav-Dateien
          image/gif *.gif GIF-Dateien
          image/jpeg *.jpeg *.jpg *.jpe JPEG-Dateien
          image/x-windowdump *.xwd X-Windows Dump
          text/css *.css CSS Stylesheet-Dateien
          text/html *.htm *.html *.shtml -Dateien
          text/java****** *.js Java******-Dateien
          text/plain *.txt reine Textdateien
          video/mpeg *.mpeg *.mpg *.mpe MPEG-Dateien
          video/vnd.rn-realvideo *.rmvb realplay-Dateien
          video/quicktime *.qt *.mov Quicktime-Dateien
          video/vnd.vivo *viv *.vivo Vivo-Dateien

          更多....查找請用ctrl+F

          MIME類型大全
          application/vnd.lotus-1-2-3
          3gp video/3gpp
          aab application/x-authoware-bin
          aam application/x-authoware-map
          aas application/x-authoware-seg
          ai application/post******
          aif audio/x-aiff
          aifc audio/x-aiff
          aiff audio/x-aiff
          als audio/X-Alpha5
          amc application/x-mpeg
          ani application/octet-stream
          asc text/plain
          asd application/astound
          asf video/x-ms-asf
          asn application/astound
          asp application/x-asap
          asx video/x-ms-asf
          au audio/basic
          avb application/octet-stream
          avi video/x-msvideo
          awb audio/amr-wb
          bcpio application/x-bcpio
          bin application/octet-stream
          bld application/bld
          bld2 application/bld2
          bmp application/x-MS-bmp
          bpk application/octet-stream
          bz2 application/x-bzip2
          cal image/x-cals
          ccn application/x-cnc
          cco application/x-cocoa
          cdf application/x-netcdf
          cgi magnus-internal/cgi
          chat application/x-chat
          class application/octet-stream
          clp application/x-msclip
          cmx application/x-cmx
          co application/x-cult3d-object
          cod image/cis-cod
          cpio application/x-cpio
          cpt application/mac-compactpro
          crd application/x-mscardfile
          csh application/x-csh
          csm chemical/x-csml
          csml chemical/x-csml
          css text/css
          cur application/octet-stream
          dcm x-lml/x-evm
          dcr application/x-director
          dcx image/x-dcx
          dhtml text/html
          dir application/x-director
          dll application/octet-stream
          dmg application/octet-stream
          dms application/octet-stream
          doc application/msword
          dot application/x-dot
          dvi application/x-dvi
          dwf drawing/x-dwf
          dwg application/x-autocad
          dxf application/x-autocad
          dxr application/x-director
          ebk application/x-expandedbook
          emb chemical/x-embl-dl-nucleotide
          embl chemical/x-embl-dl-nucleotide
          eps application/post******
          eri image/x-eri
          es audio/echospeech
          esl audio/echospeech
          etc application/x-earthtime
          etx text/x-setext
          evm x-lml/x-evm
          evy application/x-envoy
          exe application/octet-stream
          fh4 image/x-freehand
          fh5 image/x-freehand
          fhc image/x-freehand
          fif image/fif
          fm application/x-maker
          fpx image/x-fpx
          fvi video/isivideo
          gau chemical/x-gaussian-input
          gca application/x-gca-compressed
          gdb x-lml/x-gdb
          gif image/gif
          gps application/x-gps
          gtar application/x-gtar
          gz application/x-gzip
          hdf application/x-hdf
          hdm text/x-hdml
          hdml text/x-hdml
          hlp application/winhlp
          hqx application/mac-binhex40
          htm text/html
          html text/html
          hts text/html
          ice x-conference/x-cooltalk
          ico application/octet-stream
          ief image/ief
          ifm image/gif
          ifs image/ifs
          imy audio/melody
          ins application/x-NET-Install
          ips application/x-ip******
          ipx application/x-ipix
          it audio/x-mod
          itz audio/x-mod
          ivr i-world/i-vrml
          j2k image/j2k
          jad text/vnd.sun.j2me.app-de******or
          jam application/x-jam
          jar application/java-archive
          jnlp application/x-java-jnlp-file
          jpe image/jpeg
          jpeg image/jpeg
          jpg image/jpeg
          jpz image/jpeg
          js application/x-java******
          jwc application/jwc
          kjx application/x-kjx
          lak x-lml/x-lak
          latex application/x-latex
          lcc application/fastman
          lcl application/x-digitalloca
          lcr application/x-digitalloca
          lgh application/lgh
          lha application/octet-stream
          lml x-lml/x-lml
          lmlpack x-lml/x-lmlpack
          lsf video/x-ms-asf
          lsx video/x-ms-asf
          lzh application/x-lzh
          m13 application/x-msmediaview
          m14 application/x-msmediaview
          m15 audio/x-mod
          m3u audio/x-mpegurl
          m3url audio/x-mpegurl
          ma1 audio/ma1
          ma2 audio/ma2
          ma3 audio/ma3
          ma5 audio/ma5
          man application/x-troff-man
          map magnus-internal/imagemap
          mbd application/mbedlet
          mct application/x-mascot
          mdb application/x-msaccess
          mdz audio/x-mod
          me application/x-troff-me
          mel text/x-vmel
          mi application/x-mif
          mid audio/midi
          midi audio/midi
          mif application/x-mif
          mil image/x-cals
          mio audio/x-mio
          mmf application/x-skt-lbs
          mng video/x-mng
          mny application/x-msmoney
          moc application/x-mocha
          mocha application/x-mocha
          mod audio/x-mod
          mof application/x-yumekara
          mol chemical/x-mdl-molfile
          mop chemical/x-mopac-input
          mov video/quicktime
          movie video/x-sgi-movie
          mp2 audio/x-mpeg
          mp3 audio/x-mpeg
          mp4 video/mp4
          mpc application/vnd.mpohun.certificate
          mpe video/mpeg
          mpeg video/mpeg
          mpg video/mpeg
          mpg4 video/mp4
          mpga audio/mpeg
          mpn application/vnd.mophun.application
          mpp application/vnd.ms-project
          mps application/x-mapserver
          mrl text/x-mrml
          mrm application/x-mrm
          ms application/x-troff-ms
          mts application/metastream
          mtx application/metastream
          mtz application/metastream
          mzv application/metastream
          nar application/zip
          nbmp image/nbmp
          nc application/x-netcdf
          ndb x-lml/x-ndb
          ndwn application/ndwn
          nif application/x-nif
          nmz application/x-scream
          nokia-op-logo image/vnd.nok-oplogo-color
          npx application/x-netfpx
          nsnd audio/nsnd
          nva application/x-neva1
          oda application/oda
          oom application/x-AtlasMate-Plugin
          pac audio/x-pac
          pae audio/x-epac
          pan application/x-pan
          pbm image/x-portable-bitmap
          pcx image/x-pcx
          pda image/x-pda
          pdb chemical/x-pdb
          pdf application/pdf
          pfr application/font-tdpfr
          pgm image/x-portable-graymap
          pict image/x-pict
          pm application/x-perl
          pmd application/x-pmd
          png image/png
          pnm image/x-portable-anymap
          pnz image/png
          pot application/vnd.ms-powerpoint
          ppm image/x-portable-pixmap
          pps application/vnd.ms-powerpoint
          ppt application/vnd.ms-powerpoint
          pqf application/x-cprplayer
          pqi application/cprplayer
          prc application/x-prc
          proxy application/x-ns-proxy-autoconfig
          ps application/post******
          ptlk application/listenup
          pub application/x-mspublisher
          pvx video/x-pv-pvx
          qcp audio/vnd.qcelp
          qt video/quicktime
          qti image/x-quicktime
          qtif image/x-quicktime
          r3t text/vnd.rn-realtext3d
          ra audio/x-pn-realaudio
          ram audio/x-pn-realaudio
          rar application/x-rar-compressed
          ras image/x-cmu-raster
          rdf application/rdf+xml
          rf image/vnd.rn-realflash
          rgb image/x-rgb
          rlf application/x-richlink
          rm audio/x-pn-realaudio
          rmf audio/x-rmf
          rmm audio/x-pn-realaudio
          rmvb audio/x-pn-realaudio
          rnx application/vnd.rn-realplayer
          roff application/x-troff
          rp image/vnd.rn-realpix
          rpm audio/x-pn-realaudio-plugin
          rt text/vnd.rn-realtext
          rte x-lml/x-gps
          rtf application/rtf
          rtg application/metastream
          rtx text/richtext
          rv video/vnd.rn-realvideo
          rwc application/x-rogerwilco
          s3m audio/x-mod
          s3z audio/x-mod
          sca application/x-supercard
          scd application/x-msschedule
          sdf application/e-score
          sea application/x-stuffit
          sgm text/x-sgml
          sgml text/x-sgml
          sh application/x-sh
          shar application/x-shar
          shtml magnus-internal/parsed-html
          shw application/presentations
          si6 image/si6
          si7 image/vnd.stiwap.sis
          si9 image/vnd.lgtwap.sis
          sis application/vnd.symbian.install
          sit application/x-stuffit
          skd application/x-Koan
          skm application/x-Koan
          skp application/x-Koan
          skt application/x-Koan
          slc application/x-salsa
          smd audio/x-smd
          smi application/smil
          smil application/smil
          smp application/studiom
          smz audio/x-smd
          snd audio/basic
          spc text/x-speech
          spl application/futuresplash
          spr application/x-sprite
          sprite application/x-sprite
          spt application/x-spt
          src application/x-wais-source
          stk application/hyperstudio
          stm audio/x-mod
          sv4cpio application/x-sv4cpio
          sv4crc application/x-sv4crc
          svf image/vnd
          svg image/svg-xml
          svh image/svh
          svr x-world/x-svr
          swf application/x-shockwave-flash
          swfl application/x-shockwave-flash
          t application/x-troff
          tad application/octet-stream
          talk text/x-speech
          tar application/x-tar
          taz application/x-tar
          tbp application/x-timbuktu
          tbt application/x-timbuktu
          tcl application/x-tcl
          tex application/x-tex
          texi application/x-texinfo
          texinfo application/x-texinfo
          tgz application/x-tar
          thm application/vnd.eri.thm
          tif image/tiff
          tiff image/tiff
          tki application/x-tkined
          tkined application/x-tkined
          toc application/toc
          toy image/toy
          tr application/x-troff
          trk x-lml/x-gps
          trm application/x-msterminal
          tsi audio/tsplayer
          tsp application/dsptype
          tsv text/tab-separated-values
          tsv text/tab-separated-values
          ttf application/octet-stream
          ttz application/t-time
          txt text/plain
          ult audio/x-mod
          ustar application/x-ustar
          uu application/x-uuencode
          uue application/x-uuencode
          vcd application/x-cdlink
          vcf text/x-vcard
          vdo video/vdo
          vib audio/vib
          viv video/vivo
          vivo video/vivo
          vmd application/vocaltec-media-desc
          vmf application/vocaltec-media-file
          vmi application/x-dreamcast-vms-info
          vms application/x-dreamcast-vms
          vox audio/voxware
          vqe audio/x-twinvq-plugin
          vqf audio/x-twinvq
          vql audio/x-twinvq
          vre x-world/x-vream
          vrml x-world/x-vrml
          vrt x-world/x-vrt
          vrw x-world/x-vream
          vts workbook/formulaone
          wav audio/x-wav
          wax audio/x-ms-wax
          wbmp image/vnd.wap.wbmp
          web application/vnd.xara
          wi image/wavelet
          wis application/x-InstallShield
          wm video/x-ms-wm
          wma audio/x-ms-wma
          wmd application/x-ms-wmd
          wmf application/x-msmetafile
          wml text/vnd.wap.wml
          wmlc application/vnd.wap.wmlc
          wmls text/vnd.wap.wml******
          wmlsc application/vnd.wap.wml******c
          wml****** text/vnd.wap.wml******
          wmv audio/x-ms-wmv
          wmx video/x-ms-wmx
          wmz application/x-ms-wmz
          wpng image/x-up-wpng
          wpt x-lml/x-gps
          wri application/x-mswrite
          wrl x-world/x-vrml
          wrz x-world/x-vrml
          ws text/vnd.wap.wml******
          wsc application/vnd.wap.wml******c
          wv video/wavelet
          wvx video/x-ms-wvx
          wxl application/x-wxl
          x-gzip application/x-gzip
          xar application/vnd.xara
          xbm image/x-xbitmap
          xdm application/x-xdma
          xdma application/x-xdma
          xdw application/vnd.fujixerox.docuworks
          xht application/xhtml+xml
          xhtm application/xhtml+xml
          xhtml application/xhtml+xml
          xla application/vnd.ms-excel
          xlc application/vnd.ms-excel
          xll application/x-excel
          xlm application/vnd.ms-excel
          xls application/vnd.ms-excel
          xlt application/vnd.ms-excel
          xlw application/vnd.ms-excel
          xm audio/x-mod
          xml text/xml
          xmz audio/x-mod
          xpi application/x-xpinstall
          xpm image/x-xpixmap
          xsit text/xml
          xsl text/xml
          xul text/xul
          xwd image/x-xwindowdump
          xyz chemical/x-pdb
          yz1 application/x-yz1
          z application/x-compress
          zac application/x-zaurus-zac
          zip application/zip

          posted @ 2010-04-15 10:59 小菜毛毛 閱讀(291) | 評論 (0)編輯 收藏

          HttpClient 是 Apache Jakarta Common 下的子項目,可以用來提供高效的、最新的、功能豐富的支持 HTTP 協(xié)議的客戶端編程工具包,并且它支持 HTTP 協(xié)議最新的版本和建議。本文首先介紹 HTTPClient,然后根據(jù)作者實際工作經(jīng)驗給出了一些常見問題的解決方法。

          HttpClient簡介

          HTTP 協(xié)議可能是現(xiàn)在 Internet 上使用得最多、最重要的協(xié)議了,越來越多的 Java 應(yīng)用程序需要直接通過 HTTP 協(xié)議來訪問網(wǎng)絡(luò)資源。雖然在 JDK 的 java.net 包中已經(jīng)提供了訪問 HTTP 協(xié)議的基本功能,但是對于大部分應(yīng)用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協(xié)議的客戶端編程工具包,并且它支持 HTTP 協(xié)議最新的版本和建議。HttpClient 已經(jīng)應(yīng)用在很多的項目中,比如 Apache Jakarta 上很著名的另外兩個開源項目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的應(yīng)用可以參見http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。HttpClient 項目非常活躍,使用的人還是非常多的。目前 HttpClient 版本是在 2005.10.11 發(fā)布的 3.0 RC4 。





          回頁首


          HttpClient 功能介紹

          以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細(xì)的功能可以參見 HttpClient 的主頁。

          • 實現(xiàn)了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
          • 支持自動轉(zhuǎn)向
          • 支持 HTTPS 協(xié)議
          • 支持代理服務(wù)器等

          下面將逐一介紹怎樣使用這些功能。首先,我們必須安裝好 HttpClient。





          回頁首


          HttpClient 基本功能的使用

          GET 方法

          使用 HttpClient 需要以下 6 個步驟:

          1. 創(chuàng)建 HttpClient 的實例

          2. 創(chuàng)建某種連接方法的實例,在這里是 GetMethod。在 GetMethod 的構(gòu)造函數(shù)中傳入待連接的地址

          3. 調(diào)用第一步中創(chuàng)建好的實例的 execute 方法來執(zhí)行第二步中創(chuàng)建好的 method 實例

          4. 讀 response

          5. 釋放連接。無論執(zhí)行方法是否成功,都必須釋放連接

          6. 對得到后的內(nèi)容進行處理

          根據(jù)以上步驟,我們來編寫用GET方法來取得某網(wǎng)頁內(nèi)容的代碼。

          • 大部分情況下 HttpClient 默認(rèn)的構(gòu)造函數(shù)已經(jīng)足夠使用。
            HttpClient httpClient = new HttpClient();


          • 創(chuàng)建GET方法的實例。在GET方法的構(gòu)造函數(shù)中傳入待連接的地址即可。用GetMethod將會自動處理轉(zhuǎn)發(fā)過程,如果想要把自動處理 轉(zhuǎn)發(fā)過程去掉的話,可以調(diào)用方法setFollowRedirects(false)。
            GetMethod getMethod = new GetMethod("http://www.ibm.com/");


          • 調(diào)用實例httpClient的executeMethod方法來執(zhí)行g(shù)etMethod。由于是執(zhí)行在網(wǎng)絡(luò)上的程序,在運行 executeMethod方法的時候,需要處理兩個異常,分別是HttpException和IOException。引起第一種異常的原因主要可能是 在構(gòu)造getMethod的時候傳入的協(xié)議不對,比如不小心將"http"寫成"htp",或者服務(wù)器端返回的內(nèi)容不正常等,并且該異常發(fā)生是不可恢復(fù) 的;第二種異常一般是由于網(wǎng)絡(luò)原因引起的異常,對于這種異常 (IOException),HttpClient會根據(jù)你指定的恢復(fù)策略自動試著重新執(zhí)行executeMethod方法。HttpClient的恢復(fù) 策略可以自定義(通過實現(xiàn)接口HttpMethodRetryHandler來實現(xiàn))。通過httpClient的方法setParameter設(shè)置你實 現(xiàn)的恢復(fù)策略,本文中使用的是系統(tǒng)提供的默認(rèn)恢復(fù)策略,該策略在碰到第二類異常的時候?qū)⒆詣又卦?次。executeMethod返回值是一個整數(shù),表示 了執(zhí)行該方法后服務(wù)器返回的狀態(tài)碼,該狀態(tài)碼能表示出該方法執(zhí)行是否成功、需要認(rèn)證或者頁面發(fā)生了跳轉(zhuǎn)(默認(rèn)狀態(tài)下GetMethod的實例是自動處理跳 轉(zhuǎn)的)等。
            //設(shè)置成了默認(rèn)的恢復(fù)策略,在發(fā)生異常時候?qū)⒆詣又卦?次,在這里你也可以設(shè)置成自定義的恢復(fù)策略

            getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,

            new DefaultHttpMethodRetryHandler());

            //執(zhí)行g(shù)etMethod

            int statusCode = client.executeMethod(getMethod);

            if (statusCode != HttpStatus.SC_OK) {

            System.err.println("Method failed: " + getMethod.getStatusLine());

            }


          • 在返回的狀態(tài)碼正確后,即可取得內(nèi)容。取得目標(biāo)地址的內(nèi)容有三種方法:第一種,getResponseBody,該方法返回的是目標(biāo)的二進制的byte 流;第二種,getResponseBodyAsString,這個方法返回的是String類型,值得注意的是該方法返回的String的編碼是根據(jù)系 統(tǒng)默認(rèn)的編碼方式,所以返回的String值可能編碼類型有誤,在本文的"字符編碼"部分中將對此做詳細(xì)介紹;第三 種,getResponseBodyAsStream,這個方法對于目標(biāo)地址中有大量數(shù)據(jù)需要傳輸是最佳的。在這里我們使用了最簡單的 getResponseBody方法。
            byte[] responseBody = method.getResponseBody();


          • 釋放連接。無論執(zhí)行方法是否成功,都必須釋放連接。
            method.releaseConnection();


          • 處理內(nèi)容。在這一步中根據(jù)你的需要處理內(nèi)容,在例子中只是簡單的將內(nèi)容打印到控制臺。
            System.out.println(new String(responseBody));


          下面是程序的完整代碼,這些代碼也可在附件中的test.GetSample中找到。


          package test;

          import java.io.IOException;

          import org.apache.commons.httpclient.*;

          import org.apache.commons.httpclient.methods.GetMethod;

          import org.apache.commons.httpclient.params.HttpMethodParams;

          public class GetSample{

          public static void main(String[] args) {

          //構(gòu)造HttpClient的實例

          HttpClient httpClient = new HttpClient();

          //創(chuàng)建GET方法的實例

          GetMethod getMethod = new GetMethod("http://www.ibm.com");

          //使用系統(tǒng)提供的默認(rèn)的恢復(fù)策略

          getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,

          new DefaultHttpMethodRetryHandler());

          try {

          //執(zhí)行g(shù)etMethod

          int statusCode = httpClient.executeMethod(getMethod);

          if (statusCode != HttpStatus.SC_OK) {

          System.err.println("Method failed: "

          + getMethod.getStatusLine());

          }

          //讀取內(nèi)容

          byte[] responseBody = getMethod.getResponseBody();

          //處理內(nèi)容

          System.out.println(new String(responseBody));

          } catch (HttpException e) {

          //發(fā)生致命的異常,可能是協(xié)議不對或者返回的內(nèi)容有問題

          System.out.println("Please check your provided http address!");

          e.printStackTrace();

          } catch (IOException e) {

          //發(fā)生網(wǎng)絡(luò)異常

          e.printStackTrace();

          } finally {

          //釋放連接

          getMethod.releaseConnection();

          }

          }

          }


          POST方法

          根據(jù)RFC2616,對POST的解釋如下:POST方法用來向目的服務(wù)器發(fā)出請求,要求它接受被附在請求后的實體,并把它當(dāng)作請求隊列 (Request-Line)中請求URI所指定資源的附加新子項。POST被設(shè)計成用統(tǒng)一的方法實現(xiàn)下列功能:

          • 對現(xiàn)有資源的注釋(Annotation of existing resources)
          • 向電子公告欄、新聞組,郵件列表或類似討論組發(fā)送消息
          • 提交數(shù)據(jù)塊,如將表單的結(jié)果提交給數(shù)據(jù)處理過程
          • 通過附加操作來擴展數(shù)據(jù)庫

          調(diào)用HttpClient中的PostMethod與GetMethod類似,除了設(shè)置PostMethod的實例與GetMethod有些 不同之外,剩下的步驟都差不多。在下面的例子中,省去了與GetMethod相同的步驟,只說明與上面不同的地方,并以登錄清華大學(xué)BBS為例子進行說 明。

          • 構(gòu)造PostMethod之前的步驟都相同,與GetMethod一樣,構(gòu)造PostMethod也需要一個URI參數(shù),在本例中,登錄 的地址是http://www.newsmth.net/bbslogin2.php。在創(chuàng)建了PostMethod的實例之后,需要給method實例 填充表單的值,在BBS的登錄表單中需要有兩個域,第一個是用戶名(域名叫id),第二個是密碼(域名叫passwd)。表單中的域用類 NameValuePair來表示,該類的構(gòu)造函數(shù)第一個參數(shù)是域名,第二參數(shù)是該域的值;將表單所有的值設(shè)置到PostMethod中用方法 setRequestBody。另外由于BBS登錄成功后會轉(zhuǎn)向另外一個頁面,但是HttpClient對于要求接受后繼服務(wù)的請求,比如POST和 PUT,不支持自動轉(zhuǎn)發(fā),因此需要自己對頁面轉(zhuǎn)向做處理。具體的頁面轉(zhuǎn)向處理請參見下面的"自動轉(zhuǎn)向"部分。代碼如下:
            String url = "http://www.newsmth.net/bbslogin2.php";

            PostMethod postMethod = new PostMethod(url);

            // 填入各個表單域的值

            NameValuePair[] data = { new NameValuePair("id", "youUserName"),

            new NameValuePair("passwd", "yourPwd") };

            // 將表單的值放入postMethod中

            postMethod.setRequestBody(data);

            // 執(zhí)行postMethod

            int statusCode = httpClient.executeMethod(postMethod);

            // HttpClient對于要求接受后繼服務(wù)的請求,象POST和PUT等不能自動處理轉(zhuǎn)發(fā)

            // 301或者302

            if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||

            statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {

            // 從頭中取出轉(zhuǎn)向的地址

            Header locationHeader = postMethod.getResponseHeader("location");

            String location = null;

            if (locationHeader != null) {

            location = locationHeader.getValue();

            System.out.println("The page was redirected to:" + location);

            } else {

            System.err.println("Location field value is null.");

            }

            return;

            }


          完整的程序代碼請參見附件中的test.PostSample





          回頁首


          使用HttpClient過程中常見的一些問題

          下面介紹在使用HttpClient過程中常見的一些問題。

          字符編碼

          某目標(biāo)頁的編碼可能出現(xiàn)在兩個地方,第一個地方是服務(wù)器返回的http頭中,另外一個地方是得到的html/xml頁面中。

          • 在http頭的Content-Type字段可能會包含字符編碼信息。例如可能返回的頭會包含這樣子的信息:Content-Type: text/html; charset=UTF-8。這個頭信息表明該頁的編碼是UTF-8,但是服務(wù)器返回的頭信息未必與內(nèi)容能匹配上。比如對于一些雙字節(jié)語言國家,可能服務(wù) 器返回的編碼類型是UTF-8,但真正的內(nèi)容卻不是UTF-8編碼的,因此需要在另外的地方去得到頁面的編碼信息;但是如果服務(wù)器返回的編碼不是UTF- 8,而是具體的一些編碼,比如gb2312等,那服務(wù)器返回的可能是正確的編碼信息。通過method對象的getResponseCharSet()方 法就可以得到http頭中的編碼信息。
          • 對于象xml或者h(yuǎn)tml這樣的文件,允許作者在頁面中直接指定編碼類型。比如在html中會有<meta http-equiv="Content-Type" content="text/html; charset=gb2312"/>這樣的標(biāo)簽;或者在xml中會有<?xml version="1.0" encoding="gb2312"?>這樣的標(biāo)簽,在這些情況下,可能與http頭中返回的編碼信息沖突,需要用戶自己判斷到底那種編碼類型應(yīng)該 是真正的編碼。

          自動轉(zhuǎn)向

          根據(jù)RFC2616中對自動轉(zhuǎn)向的定義,主要有兩種:301和302。301表示永久的移走(Moved Permanently),當(dāng)返回的是301,則表示請求的資源已經(jīng)被移到一個固定的新地方,任何向該地址發(fā)起請求都會被轉(zhuǎn)到新的地址上。302表示暫時 的轉(zhuǎn)向,比如在服務(wù)器端的servlet程序調(diào)用了sendRedirect方法,則在客戶端就會得到一個302的代碼,這時服務(wù)器返回的頭信息中 location的值就是sendRedirect轉(zhuǎn)向的目標(biāo)地址。

          HttpClient支持自動轉(zhuǎn)向處理,但是象POST和PUT方式這種要求接受后繼服務(wù)的請求方式,暫時不支持自動轉(zhuǎn)向,因此如果碰到 POST方式提交后返回的是301或者302的話需要自己處理。就像剛才在POSTMethod中舉的例子:如果想進入登錄BBS后的頁面,必須重新發(fā)起 登錄的請求,請求的地址可以在頭字段location中得到。不過需要注意的是,有時候location返回的可能是相對路徑,因此需要對 location返回的值做一些處理才可以發(fā)起向新地址的請求。

          另外除了在頭中包含的信息可能使頁面發(fā)生重定向外,在頁面中也有可能會發(fā)生頁面的重定向。引起頁面自動轉(zhuǎn)發(fā)的標(biāo)簽是:<meta http-equiv="refresh" content="5; url=http://www.ibm.com/us">。如果你想在程序中也處理這種情況的話得自己分析頁面來實現(xiàn)轉(zhuǎn)向。需要注意的是,在上面那 個標(biāo)簽中url的值也可以是一個相對地址,如果是這樣的話,需要對它做一些處理后才可以轉(zhuǎn)發(fā)。

          處理HTTPS協(xié)議

          HttpClient提供了對SSL的支持,在使用SSL之前必須安裝JSSE。在Sun提供的1.4以后的版本中,JSSE已經(jīng)集成到 JDK中,如果你使用的是JDK1.4以前的版本則必須安裝JSSE。JSSE不同的廠家有不同的實現(xiàn)。下面介紹怎么使用HttpClient來打開 Https連接。這里有兩種方法可以打開https連接,第一種就是得到服務(wù)器頒發(fā)的證書,然后導(dǎo)入到本地的keystore中;另外一種辦法就是通過擴 展HttpClient的類來實現(xiàn)自動接受證書。

          方法1,取得證書,并導(dǎo)入本地的keystore:

          • 安裝JSSE (如果你使用的JDK版本是1.4或者1.4以上就可以跳過這一步)。本文以IBM的JSSE為例子說明。先到IBM網(wǎng)站上下載JSSE的安裝包。然后解 壓開之后將ibmjsse.jar包拷貝到<java-home>"lib"ext"目錄下。
          • 取得并且導(dǎo)入證書。證書可以通過IE來獲得:

            1. 用IE打開需要連接的https網(wǎng)址,會彈出如下對話框:



            2. 單擊"View Certificate",在彈出的對話框中選擇"Details",然后再單擊"Copy to File",根據(jù)提供的向?qū)纱L問網(wǎng)頁的證書文件



            3. 向?qū)У谝徊剑瑲g迎界面,直接單擊"Next",



            4. 向?qū)У诙?,選擇導(dǎo)出的文件格式,默認(rèn),單擊"Next",



            5. 向?qū)У谌剑斎雽?dǎo)出的文件名,輸入后,單擊"Next",



            6. 向?qū)У谒牟?,單?Finish",完成向?qū)?/p>

            7. 最后彈出一個對話框,顯示導(dǎo)出成功



          • 用keytool工具把剛才導(dǎo)出的證書倒入本地keystore。Keytool命令在<java-home>"bin "下,打開命令行窗口,并到<java-home>"lib"security"目錄下,運行下面的命令:

            keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file your.cer


            其中參數(shù)alias后跟的值是當(dāng)前證書在keystore中的唯一標(biāo)識符,但是大小寫不區(qū)分;參數(shù)file后跟的是剛才通過IE導(dǎo)出的證 書所在的路徑和文件名;如果你想刪除剛才導(dǎo)入到keystore的證書,可以用命令:

            keytool -delete -keystore cacerts -storepass changeit -alias yourEntry1


          • 寫程序訪問https地址。如果想測試是否能連上https,只需要稍改一下GetSample例子,把請求的目標(biāo)變成一個https地 址。
            GetMethod getMethod = new GetMethod("https://www.yourdomain.com");


            運行該程序可能出現(xiàn)的問題:

            1. 拋出異常java.net.SocketException: Algorithm SSL not available。出現(xiàn)這個異常可能是因為沒有加JSSEProvider,如果用的是IBM的JSSE Provider,在程序中加入這樣的一行:

             if(Security.getProvider("com.ibm.jsse.IBMJSSEProvider") == null)

            Security.addProvider(new IBMJSSEProvider());


            或者也可以打開<java-home>"lib"security"java.security,在行

            security.provider.1=sun.security.provider.Sun

            security.provider.2=com.ibm.crypto.provider.IBMJCE


            后面加入security.provider.3=com.ibm.jsse.IBMJSSEProvider

            2. 拋出異常java.net.SocketException: SSL implementation not available。出現(xiàn)這個異常可能是你沒有把ibmjsse.jar拷貝到<java-home>"lib"ext"目錄下。

            3. 拋出異常javax.net.ssl.SSLHandshakeException: unknown certificate。出現(xiàn)這個異常表明你的JSSE應(yīng)該已經(jīng)安裝正確,但是可能因為你沒有把證書導(dǎo)入到當(dāng)前運行JRE的keystore中,請按照前 面介紹的步驟來導(dǎo)入你的證書。

          方法2,擴展HttpClient類實現(xiàn)自動接受證書

          因為這種方法自動接收所有證書,因此存在一定的安全問題,所以在使用這種方法前請仔細(xì)考慮您的系統(tǒng)的安全需求。具體的步驟如下:

          • 提供一個自定義的socket factory(test.MySecureProtocolSocketFactory)。這個自定義的類必須實現(xiàn)接口 org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory,在實現(xiàn)接口 的類中調(diào)用自定義的X509TrustManager(test.MyX509TrustManager),這兩個類可以在隨本文帶的附件中得到
          • 創(chuàng)建一個org.apache.commons.httpclient.protocol.Protocol的實例,指定協(xié)議名稱和默認(rèn) 的端口號
            Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);


          • 注冊剛才創(chuàng)建的https協(xié)議對象
            Protocol.registerProtocol("https ", myhttps);


          • 然后按照普通編程方式打開https的目標(biāo)地址,代碼請參見test.NoCertificationHttpsGetSample

          處理代理服務(wù)器

          HttpClient中使用代理服務(wù)器非常簡單,調(diào)用HttpClient中setProxy方法就可以,方法的第一個參數(shù)是代理服務(wù)器地 址,第二個參數(shù)是端口號。另外HttpClient也支持SOCKS代理。


          httpClient.getHostConfiguration().setProxy(hostName,port);






          回頁首


          結(jié)論

          從上面的介紹中,可以知道HttpClient對http協(xié)議支持非常好,使用起來很簡單,版本更新快,功能也很強大,具有足夠的靈活性和擴 展性。對于想在Java應(yīng)用中直接訪問http資源的編程人員來說,HttpClient是一個不可多得的好工具。



          參考資料

          • Commons logging包含了各種各樣的日志API的實現(xiàn),讀者可以通過站點http://jakarta.apache.org/commons /logging/得到詳細(xì)的內(nèi)容

          • Commons codec包含了一些一般的解碼/編碼算法。包含了語音編碼、十六進制、Base64和URL編碼等,通過http: //jakarta.apache.org/commons/codec/可以得到詳細(xì)的內(nèi)容

          • rfc2616是關(guān)于 HTTP/1.1的文檔,可以在http://www.faqs.org/rfcs/rfc2616.html上得到詳細(xì)的內(nèi)容,另外rfc1945是關(guān) 于HTTP/1.0的文檔,通過http://www.faqs.org/rfcs/rfc1945.html可以得到詳細(xì)內(nèi)容

          • SSL――SSL 是由 Netscape Communications Corporation 于 1994 年開發(fā)的,而 TLS V1.0 是由 Internet Engineering Task Force(IETF)定義的標(biāo)準(zhǔn),它基于 SSL V3.0,并且在使用的加密算法上與其有些許的不同。例如,SSL 使用 Message Authentication Code(MAC)算法來生成完整性校驗值,而 TLS 應(yīng)用密鑰的 Hashing for Message Authentication Code(HMAC)算法。

          • IBM JSSE提供了SSL(Secure Sockets Layer)和TLS(Transport Layer Security)的java實現(xiàn),在http://www-03.ibm.com/servers/eserver/zseries/software /java/jsse.html中可以得到詳細(xì)的信息

          • Keytool是一個管理密鑰和證書的工具。關(guān)于它詳細(xì)的使用信 息可以在http://www.doc.ic.ac.uk/csg/java/1.3.1docs/tooldocs/solaris /keytool.html上得到

          • HTTPClient的主頁是http://jakarta.apache.org /commons/httpclient/,你可以在這里得到關(guān)于HttpClient更加詳細(xì)的信息
          posted @ 2010-04-09 14:38 小菜毛毛 閱讀(832) | 評論 (0)編輯 收藏

          http://update1.aptana.org/studio/3.2/024747/index.html
          在以上網(wǎng)址中可以下載插件或者在線安裝插件:

          End of Life Aptana Studio 1.2

          This update site is for Aptana Studio 1.2 users. There is already a newer version of Aptana Studio available. Please check it out at http://aptana.org/studio/download

          Aptana Studio 3.2 and 3.3 Update Site

          This site is designed to be used inside Eclipse 3.2 or manually update an old version of Aptana Studio. If you have Aptana Studio installed, it is recommended you use the internal update mechanism available via the Help menu => Check for Aptana Updates...

          Install Aptana Studio as a Plugin

          For Eclipse 3.2 or Eclipse 3.3

          If you're already familiar with installing plugins from Eclipse, you can use this URL for the update site:
          http://update.aptana.com/update/studio/3.2
          For detailed instructions click here.

          For Eclipse 3.4

          For Eclipse 3.4 installation instructions click here

          From a Local File

          1. Save the above file to an easy to find location.
          2. Open Eclipse, and go to Help > Software Updates > Find and Install
          3. Search for new features to install, then click "Next" then choose "New Archived Site". Choose the file you saved in step 1.
          4. Select the appropriate plugins to install, then click "Next", accept the license agreements, and click "Next" again.
          5. Click "Change location". If no appropriate location is already available, click "Add Location" and choose something like "D:"dev"extensions"pluginname" or "extesnions"aptana".
          6. Click "Finish".

          Update Aptana Studio Standalone from a Local File

          1. Save the above file to an easy-to-find location, preferably in the root of your drive.
          2. Unzip the file into a folder.
          3. Make sure fix_policy.sh (OS X and Linux) or fix_policy.vbs (Windows) is executable
          4. Run fix_policy.sh (OS X and Linux) or fix_policy.vbs (Windows)
          5. Open policy_url.txt and copy the URL into your clipboard.
          6. Open Aptana Studio, and go to Window > Preferences > Install/Update
          7. Paste the URL from policy_url.txt (something similar to file:///path/to/policy.xml) into the Policy URL field
          8. Click "OK".
          9. Go to Help > Check for Aptana Studio Updates now...
          10. In the "Updates" window, check the box next to the name of the plug-in, and click the "Next" button.
          11. Choose the option to accept the terms of the license agreement, and click the "Next" button.
          12. Click the "Finish" button.
          13. Click the "Install All" button.
          如果按照以上方法安裝有沖突,即可將其下載的插件解壓(比如我解壓到D:/myeclipse6.0.1/eclipse/aptana_update_3.3),并把對應(yīng)的文件復(fù)制features和plugins,并在D:/myeclipse6.0.1/eclipse/links目錄下新建aptana.link文件,并編輯:path=D:\\myeclipse6.0.1\\eclipse\\aptana_update_3.3
          解決開啟后報錯java.lang.NullPointerException的問題
                開啟后彈出對話框報錯java.lang.NullPointerException,點擊details,他報錯:

          java.lang.NullPointerException
          at com.aptana.ide.xul.FirefoxBrowser.createControl(FirefoxBrowser.java:314)
          at com.aptana.ide.server.portal.ui.MyAptanaEditor.createPartControl(MyAptanaEditor.java:261)
          at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:596)
          ........... 省略.............

                這時,雖我已經(jīng)安裝了firefox,但還是要選擇windows->Preferences->My Aptana/Message Center-> "Use Firefox as the Aptana Home Page Browser",去掉勾子就解決了,My Aptana的廬山真面目就欣賞到了

          posted @ 2010-04-08 10:40 小菜毛毛 閱讀(2804) | 評論 (0)編輯 收藏

             * struts1.2和webwork的區(qū)別
              * hibernate和ibatis的區(qū)別
              * spring工作機制,IOC容器
              * servlet的一些相關(guān)問題
              * webservice相關(guān)
              * java基礎(chǔ):jvm,HashSet等等
              * 考察學(xué)習(xí)新技術(shù)的能力
          posted @ 2010-04-08 09:37 小菜毛毛 閱讀(619) | 評論 (0)編輯 收藏

          僅列出標(biāo)題
          共17頁: First 上一頁 3 4 5 6 7 8 9 10 11 下一頁 Last 
          主站蜘蛛池模板: 来凤县| 恩平市| 和政县| 逊克县| 永丰县| 旌德县| 葫芦岛市| 澎湖县| 景德镇市| 罗田县| 星子县| 聂拉木县| 阿勒泰市| 黄龙县| 洪洞县| 平泉县| 沂水县| 宜川县| 乌拉特后旗| 陆丰市| 大厂| 民丰县| 连山| 都安| 永丰县| 监利县| 西盟| 和林格尔县| 富裕县| 阿尔山市| 龙里县| 竹北市| 北票市| 营口市| 郴州市| 余江县| 昭平县| 武陟县| 井研县| 西昌市| 高淳县|