搜尋此網誌

2013年8月17日 星期六

【Java】外部設定檔的應用(java.util.Properties)

在code的過程中,總會有部分設定,可以直接寫死在檔案中
但希望將來是可以直接透過外部修改某文字檔案內容
code在根據此文件修改,做出相對應的修改動作
而不用每次都透過更新程式碼部分變數(參數),就又要重新comple code
非常沒必要。


所以需要一個可以直接引用外部參數的方法。
而java.util.Properties剛好可以滿足我們需求
透過Properties可以產生key-value pair的.xml或者是.properties並讀取key對映到的value


  • 常見應用:

    • 連線IP位址
    • 某些路徑的設定
    • i18n多國語言(.properties)

    以下部分內容轉載自[1],原文太過冗長,螢光部分較須先了解,橘色部分額外添加

    import java.io.*;
    import java.util.Properties;

    private static Properties props = new Properties();

    //一個key對應一個value

    props.setProperty("key1", "value1");
    props.setProperty("key2", "中文測試");

    System.out.println("在console 印出props中所有的(key, value)配對");
    props.list(System.out);
    System.out.println();

    //重覆設定相同的key不同的value,則key對映之舊value會被新value覆蓋
    System.out.println("印出更改後所有的(key, value)配對");
    props.setProperty("key1", "更改value1");
    props.list(System.out);
    System.out.println();

    try {
        // 輸出props中所有的(key, value)配對到xml(storeToXML)及txt(store)
        // 輸出後Stream不會自動關閉必須手動關閉,否則有可能出錯(不是在()中使用new時)
        // storeToXML(OutputStream os, Stirng comment, String encode)
        // storeToXML(OutputStream os, Stirng comment) encode預設使用 UTF-8
           props.storeToXML(new FileOutputStream("properties.xml"), "storeToXML");
           props.store(new FileOutputStream("properties.properties"), "store");
        } catch (FileNotFoundException e) {
           e.printStackTrace();
        } catch (IOException e) {
           e.printStackTrace();
        }

    props.clear();

    try {
        // props.getProperty(key)讀出(key, value)配對
        // props.getProperty(String key, String defaultWhenNotFound)
        // props.getProperty(String key) throws exception when not found
           System.out.println("props.getProperty(key)讀出(key, value)配對");
       
    // default value test
           props.load(new FileInputStream("properties.properties"));
           System.out.println(props.getProperty("key", "test"));   

           System.out.println(props.getProperty("key1"));
           props.clear();
           System.out.println();
        } catch (FileNotFoundException e) {
           e.printStackTrace();
        } catch (IOException e) {
           e.printStackTrace();
        }

    try {
        // 印出從 properties.xml 讀出的所有(key, value)配對
           System.out.println("印出properties.xml讀出的所有(key, value)配對");
           props.loadFromXML(new FileInputStream("properties.xml"));
           props.setProperty("key3", "new value");
           props.list(System.out);

        // 將新配對寫回 properties.xml,串流沒出錯
           props.storeToXML(new FileOutputStream("properties.xml"), "storeToXML");
        } catch (FileNotFoundException e) {
           e.printStackTrace();
        } catch (IOException e) {
           e.printStackTrace();
        }

    }
    ----------------------------------------------------------
    輸出結果:
    在console 印出props中所有的(key, value)配對
     -- listing properties --
     key2=中文測試
     key1=value1

     印出更改後所有的(key, value)配對
     -- listing properties --
     key2=中文測試
     key1=更改value1

     props.getProperty(key)讀出(key, value)配對
     test
     更改value1

     印出properties.xml讀出的所有(key, value)配對
     -- listing properties --
     key3=new value
     key2=中文測試
     key1=更改value1
    ----------------------------------------------------------
    產生的 properties.properties內容:
    #store
    #Sat Aug 17 15:39:54 CST 2013
    key2=\u4E2D\u6587\u6E2C\u8A66
    key1=\u66F4\u6539value1
    使用 store 所產生的文件並不直接支援中文,所以建議使用 storeToXML

    假如為了要看的見中文而使用xml會使得檔案的字元數變得更多,讓檔案size變得更大。不是一個好的建議方法。而是依照使用需求再做決定xml還是properties。

    ----------------------------------------------------------
    產生的 properties.xml內容:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
    <comment>storeToXML</comment>
    <entry key="key3">new value</entry>
    <entry key="key2">中文測試</entry>
    <entry key="key1">更改value1</entry>
    </properties>


    在Eclipse讀取properties檔案下,預設的text editor會把中文顯示成Unicode的編碼方式,實際上系統讀進來的字還是對的。所以解決的點應該是讓properties可以顯示中文。 解決方法

    2013年8月16日 星期五

    【轉載】Java中“為了性能”需做的26件事

    全文轉貼自:
    http://www.csdn.net/article/2012-06-01/2806249

    最近的機器記憶體又爆滿了,除了新增機器記憶體外,還應該好好review一下我們的代碼,有很多代碼編寫過於隨意化,這些不好的習慣或對程式語言的不瞭解是應該好好打壓打壓了。

    下面是參考網路資源總結的一些在Java程式設計中盡可能要做到的一些地方。

    1.儘量在合適的場合使用單例

    使用單例可以減輕載入的負擔,縮短載入的時間,提高載入的效率,但並不是所有地方都適用于單例,簡單來說,單例主要適用於以下三個方面:

    控制資源的使用,通過執行緒同步來控制資源的併發訪問;
    控制實例的產生,以達到節約資源的目的;
    控制資料共用,在不建立直接關聯的條件下,讓多個不相關的進程或執行緒之間實現通信。

    2.儘量避免隨意使用靜態變數

    要知道,當某個物件被定義為stataic的變數所引用,那麼GC通常是不會回收這個物件所佔有的記憶體,如

    public class A{ static B b = new B();} 此時靜態變數b的生命週期與A類同步,如果A類不會卸載,那麼b物件會常駐記憶體,直到程式終止。

    3.儘量避免過多過常的創建Java物件

    儘量避免在經常調用的方法,迴圈中new物件,由於系統不僅要花費時間來創建物件,而且還要花時間對這些物件進行垃圾回收和處理,在我們可以控制的範圍內,最大限度的重用物件,最好能用基本的資料類型或陣列來替代物件。

    4.儘量使用final修飾符

    帶有final修飾符的類是不可派生的。在Java核心API中,有許多應用final的例子,例如java.lang.String。為String類指定final防止使用者覆蓋length()方法。另外,如果一個類是final的,則該類所有方法都是final的。Java編譯器會尋找機會內聯(inline)所有的final方法(這和具體的編譯器實現有關)。此舉能夠使性能平均提高50%。

    5.儘量使用區域變數

    調用方法時傳遞的參數以及在調用中創建的臨時變數都保存在棧(Stack)中,速度較快。其他變數,如靜態變數、執行個體變數等,都在堆(Heap)中創建,速度較慢。

    6.儘量處理好包裝類型和基本類型兩者的使用場所

    雖然包裝類型和基本類型在使用過程中是可以相互轉換,但它們兩者所產生的記憶體區域是完全不同的,基本類型資料產生和處理都在棧中處理,包裝類型是物件,是在堆中產生實例。

    在集合類物件中,有物件方面需要的處理適用包裝類型,其他的處理提倡使用基本類型。

    7.慎用synchronized,儘量減小synchronize的方法

    都知道,實現同步是要很大的系統開銷作為代價的,甚至可能造成鎖死,所以儘量避免無謂的同步控制。synchronize方法被調用時,直接會把當前物件鎖了,在方法執行完之前其他執行緒無法調用當前物件的其他方法。所以synchronize的方法儘量小,並且應儘量使用方法同步代替代碼塊同步。

    8.儘量使用StringBuilder和StringBuffer進行字元串連接

    這個就不多講了。

    9.儘量不要使用finalize方法

    實際上,將資源清理放在finalize方法中完成是非常不好的選擇,由於GC的工作量很大,尤其是回收Young代記憶體時,大都會引起應用程式暫停,所以再選擇使用finalize方法進行資源清理,會導致GC負擔更大,程式運行效率更差。

    10.儘量使用基底資料型別代替物件

    String str = "hello"; 上面這種方式會創建一個“hello”字串,而且JVM的字元緩存池還會緩存這個字串;

    String str = new String("hello"); 此時程式除創建字串外,str所引用的String物件底層還包含一個char[]陣列,這個char[]陣列依次存放了h,e,l,l,o

    11.單執行緒應儘量使用HashMap、ArrayList

    HashTable、Vector等使用了同步機制,降低了性能。

    12.儘量合理的創建HashMap

    當你要創建一個比較大的hashMap時,要充分利用另一個構造函數public HashMap(int initialCapacity, float loadFactor)避免HashMap多次進行了hash重構,擴容是一件很耗費性能的事,在預設中initialCapacity只有16,而loadFactor是 0.75,需要多大的容量,你最好能準確的估計你所需要的最佳大小,同樣的Hashtable,Vectors也是一樣的道理。

    13.儘量減少對變數的重複計算 



    for(int i=0;i<list.size();i++)應該改為

    for(int i=0,len=list.size();i<len;i++)並且在迴圈中應該避免使用複雜的運算式,在迴圈中,迴圈條件會被反復計算,如果不使用複雜運算式,而使迴圈條件值不變的話,程式將會運行的更快。

    14.儘量避免不必要的創建



    A a = new A(); if(i==1){list.add(a);}應該改為

    if(i==1){ A a = new A();list.add(a);}

    15.儘量在finally塊中釋放資源

    程式中使用到的資源應當被釋放,以避免資源洩漏。這最好在finally塊中去做。不管程式執行的結果如何,finally塊總是會執行的,以確保資源的正確關閉。

    16.儘量使用移位來代替'a/b'的操作

    “/”是一個代價很高的操作,使用移位的操作將會更快和更有效



    int num = a / 4; int num = a / 8;應該改為

    int num = a 》 2; int num = a 》 3;但注意的是使用移位應添加注釋,因為移位操作不直觀,比較難理解。

    17.儘量使用移位來代替'a*b'的操作

    同樣的,對於'*'操作,使用移位的操作將會更快和更有效



    int num = a * 4; int num = a * 8;應該改為

    int num = a 《 2; int num = a 《 3;

    18.儘量確定StringBuffer的容量

    StringBuffer的構造器會創建一個默認大小(通常是16)的字元陣列。在使用中,如果超出這個大小,就會重新分配記憶體,創建一個更大的陣列,並將原先的陣列複製過來,再丟棄舊的陣列。在大多數情況下,你可以在創建StringBuffer的時候指定大小,這樣就避免了在容量不夠的時候自動增長,以提高性能。

    如:

    StringBuffer buffer = new StringBuffer(1000);

    19.儘量早釋放無用對象的引用

    大部分時間,方法局部引用變數所引用的物件會隨著方法結束而變成垃圾,因此,大部分時候程式無需將局部,引用變數顯式設為null.

    例如:

    Public void test(){ Object obj = new Object(); …… Obj=null; }上面這個就沒必要了,隨著方法test()的執行完成,程式中obj引用變數的作用域就結束了。但是如果是改成下面:

    Public void test(){ Object obj = new Object(); …… Obj=null;//執行耗時,耗記憶體操作;或調用耗時,耗記憶體的方法 …… } 這時候就有必要將obj賦值為null,可以儘早的釋放對Object物件的引用。

    20.儘量避免使用二維陣列

    二維資料佔用的記憶體空間比一維陣列多得多,大概10倍以上。

    21.儘量避免使用split

    除非是必須的,否則應該避免使用split,split由於支持規則運算式,所以效率比較低,如果是頻繁的幾十,幾百萬的調用將會耗費大量資源,如果確實需要頻繁的調用split,可以考慮使用apache的StringUtils.split(string,char),頻繁split的可以緩存結果。

    22.ArrayList&LinkedList

    一個是線性表,一個是鏈表,一句話,隨機查詢儘量使用ArrayList,ArrayList優於LinkedList,LinkedList還要移動指標,添加刪除的操作LinkedList優於ArrayList,ArrayList還要移動資料,不過這是理論性分析,事實未必如此,重要的是理解好2者的資料結構,對症下藥。

    23.儘量使用System.arraycopy()代替通過來迴圈複製陣列

    System.arraycopy()要比通過迴圈來複製陣列快的多。

    24.儘量緩存經常使用的物件

    盡可能將經常使用的物件進行緩存,可以使用陣列,或HashMap的容器來進行緩存,但這種方式可能導致系統佔用過多的緩存,性能下降,推薦可以使用一些協力廠商的開源工具,如EhCache,Oscache進行緩存,他們基本都實現了FIFO/FLU等緩存演算法。

    25.儘量避免非常大的記憶體分配

    有時候問題不是由當時的堆狀態造成的,而是因為分配失敗造成的。分配的區塊都必須是連續的,而隨著堆越來越滿,找到較大的連續塊越來越困難。

    26.慎用異常

    當創建一個異常時,需要收集一個棧跟蹤(stack track),這個棧跟蹤用於描述異常是在何處創建的。構建這些棧跟蹤時需要為運行時棧做一份快照,正是這一部分開銷很大。當需要創建一個Exception時,JVM不得不說:先別動,我想就您現在的樣子存一份快照,所以暫時停止入棧和出棧操作。棧跟蹤不只包含運行時棧中的一兩個元素,而是包含這個棧中的每一個元素。

    如果您創建一個Exception,那麼就得付出代價。好在捕獲異常開銷不大,因此可以使用try-catch將核心內容包起來。從技術上講,您甚至可以隨意地拋出異常,而不用花費很大的代價。招致性能損失的並不是throw操作(儘管在沒有預先創建異常的情況下就拋出異常是有點不尋常)。真正要花代價的是創建異常。幸運的是,好的程式設計習慣已教會我們,不應該不管三七二十一就拋出異常。異常是為異常的情況而設計的,使用時也應該牢記這一原則。

    【Java】SWT examples in Clojure

    SWT Examples in Clojure

    2013年7月31日 星期三

    【SQL】使用JOIN觀念

    參考來源:Join (SQL) - Wikipedia, the free encyclopediaA Visual Explanation of SQL Joins
    • 大致分為幾類:
      1. Inner Join
        • Natural Join
      2. Outer Join
        1. Left Outer Join
        2. Right Outer Join
        3. Full Outer Join
      3. Cross Join
      4. Self-Join
    建立如下測試資料:
     (designated Department.DepartmentID is the primary key and Employee.DepartmentID is a foreign key),建立方法參考按此

    Inner Join-只會回傳join條件中有匹配的資料

    inner可省略,通常使用join+表格後面需接on+條件。
    範例:
    SELECT *
    FROM employee INNER JOIN department
      ON employee.DepartmentID = department.DepartmentID;
    

    其結果與下面語法、效能相同,但建議使用上面的方法:

    SELECT *
    FROM employee, department
    WHERE employee.DepartmentID = department.DepartmentID;

    Natural Join-只回傳條件中匹配的資料,但相同欄位名稱只會出現一次

    SELECT *
    FROM employee NATURAL JOIN department;
    
    

    Outer Join-回傳單一邊資料表中的資料列,及另一邊資料表中符合join條件中匹配的資料列。

    包含Left Outer Join、Right Outer Join和Full Outer Join三種類型,其中Outer關鍵字可省略

    - Left Outer Join
    以Employee為主,去Join Department。

    SELECT *
    FROM employee LEFT OUTER JOIN department
      ON employee.DepartmentID = department.DepartmentID;


    - Right Outer Join
    Department為主,去Join Employee

    SELECT *
    FROM employee RIGHT OUTER JOIN department
      ON employee.DepartmentID = department.DepartmentID;

    - Full Outer Join-即為Left和Right Join的聯集,會回傳左右資料表中所有記錄,不論是否符合Join條件。

    SELECT *
    FROM employee FULL OUTER JOIN department
      ON employee.DepartmentID = department.DepartmentID;

    Cross Join-會回傳兩資料表間的笛卡兒乘積 (Cartesian product),也就是所有可能的排列組合,小心使用,回傳資料很龐大。注意不能指定條件。

    SELECT *
    FROM employee CROSS JOIN department;

    其結果與下面語法、效能相同,但建議使用上面的方法:
    
    
    SELECT *
    FROM employee, department;

    Self-Join - 自己和自己做聯集。
    舉例想知道每個僱員的上司名稱,可以把自己表格做自我連接。舉例按此

    【SQL】使用Create指令

    如何建立如右二表?

    CREATE TABLE department
    (
     DepartmentID INT,
     DepartmentName VARCHAR(20)
    );
     
    CREATE TABLE employee
    (
     LastName VARCHAR(20),
     DepartmentID INT
    );
     
    INSERT INTO department(DepartmentID, DepartmentName) VALUES(31, 'Sales');
    INSERT INTO department(DepartmentID, DepartmentName) VALUES(33, 'Engineering');
    INSERT INTO department(DepartmentID, DepartmentName) VALUES(34, 'Clerical');
    INSERT INTO department(DepartmentID, DepartmentName) VALUES(35, 'Marketing');
     
    INSERT INTO employee(LastName, DepartmentID) VALUES('Rafferty', 31);
    INSERT INTO employee(LastName, DepartmentID) VALUES('Jones', 33);
    INSERT INTO employee(LastName, DepartmentID) VALUES('Steinberg', 33);
    INSERT INTO employee(LastName, DepartmentID) VALUES('Robinson', 34);
    INSERT INTO employee(LastName, DepartmentID) VALUES('Smith', 34);
    INSERT INTO employee(LastName, DepartmentID) VALUES('John', NULL);
    

    2013年6月13日 星期四

    【Java】實作從網址下載pdf檔案

    package Crawler;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.URL;
    import java.net.URLConnection;
    
    /**
     * @author PTODUE
     *
     */
    public class SavePdf {
    
    
     public static void main(String[] args) throws IOException {
      // TODO Auto-generated method stub
      String path = "http://XXX.XXX.XXX.XXX/a/b/XXXX.pdf";  //下載檔案的網址
      
      String filePath = url.getFile();   //檔案路徑  ex:a/b/XXXX.pdf
      String fileName ="";    //儲存檔名
      
      /*
       *取出XXXX.pdf
       *
      /
      int start = filePath.lastIndexOf("/") + 1;
            int end = filePath.lastIndexOf("?", start);
            if (end == -1)
                end = filePath.length();
            fileName = filePath.substring(start, end);
      
      String outputFile = "C:/downkload/"+fileName; // 要下載檔案的位置
      File desFile = new File(outputFile);
    
      if (desFile.exists())
       desFile.delete();
      
      
      URL url = new URL(path);
      URLConnection connection = url.openConnection();
      
      byte[] buffer = new byte[1024]; // InputStream
    
      // 設定接收資料流來源 ,就是要下載的網址
      BufferedInputStream bufferedInputStream = new BufferedInputStream(connection.getInputStream());
      // 設定 儲存要下載檔案的位置.
      BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(desFile));
      int length = -1;
      while ((length = bufferedInputStream.read(buffer)) != -1) {
       bufferedOutputStream.write(buffer,0,length);
      }
      bufferedOutputStream.flush();// 將緩衝區中的資料全部寫出
      bufferedInputStream.close(); // 關閉資料流
      bufferedOutputStream.close();
      System.out.println("下載完成");
    
     }
    }
    

    2013年6月12日 星期三

    【Music】My Body Is A Cage


    "My Body Is A Cage"
    牢寵之軀

    My body is a cage
    我的軀體如同牢籠
    That keeps me from dancing with the one I love 
    阻止我與所愛之人一同共舞
    But my mind holds the key
    但我的思緒能將其開啟

    My body is a cage
    我的軀體如同牢籠
    That keeps me from dancing with the one I love 
    阻止我與所愛之人一同共舞
    But my mind holds the key
    但我的思緒能將其開啟

    I'm standing on a stage
    我站在臺上
    Of fear and self-doubt
    充滿恐懼 缺乏自信
    It's a hollow play
    這場戲碼毫無價值
    But they'll clap anyway
    但觀眾仍會為我鼓掌

    My body is a cage
    我的軀體如同牢籠
    That keeps me from dancing with the one I love 
    它阻止我與所愛之人一同共舞
    But my mind holds the key
    但我的思緒能將其開啟

    You're standing next to me
    你就站在我身邊
    My mind holds the key
    我的思緒能將其開啟

    I'm living in an age
    我活在某個世代
    That calls darkness light
    人們稱黑暗為光明
    Though my language is dead
    儘管我已喪失語言能力
    Still the shapes fill my head
    腦子仍忘不了那模樣

    I'm living in an age
    我活在某個世代
    Whose name I don't know
    不知道名稱為何
    Though the fear keeps me moving 
    儘管恐懼逼我前進
    Still my heart beats so slow
    我的心跳卻依舊緩慢

    My body is a cage
    我的軀體如同牢籠
    That keeps me from dancing with the one I love 
    阻止我與所愛之人一同共舞
    But my mind holds the key
    但我的思緒能將其開啟

    You're standing next to me
    你就站在我身邊
    My mind holds the key
    我的思緒能將其開啟
    My body is a
    我的軀體是個…

    My body is a cage 
    我的軀體如同牢籠
    We take what we're given
    我們接受賜與的恩惠
    Just because you've forgotten 
    只因罪惡已被遺忘
    That don't mean you're forgiven
    並非已被世人原諒

    I'm living in an age
    我活在某個世代
    That screams my name at night
    晚上有人大喊我的名字
    But when I get to the doorway
    等我走到門口
    There's no one in sight
    卻發現空無一人

    My body is a cage
    我的軀體如同牢籠
    That keeps me from dancing with the one I love 
    阻止我與所愛之人一同共舞
    But my mind holds the key
    但我的思緒能將其開啟

    You're standing next to me
    你就站在我身邊
    My mind holds the key
    我的思緒能將其開啟

    Set my spirit free
    解放我的靈魂
    Set my spirit free
    解放我的靈魂
    Set my body free 
    解放我的軀體

    【Java】中文URL和URI的轉換

    最近在做Crawler,爬回來的超連結發現,有些明明就是中文的網址,在瀏覽器上也是顯示中文,去查網頁的編碼是UTF-8沒錯但是抓回來的中文網址卻變成英文、數字、和百分比符號顯示亂碼的字串。
    估狗後,這些亂碼並不是真的亂馬1/2(誤),而是URI編碼。欲知詳情,請見URL編碼

    URL  <-----> URI
    以下只是臨時打的範例,不確定與法有無正確。參考參考。

    import java.net.URLDecoder;
    import java.net.URLEncoder;


    String test = "URI編碼";
    String demo ="";

    demo = URLEncoder.decode(test , "UTF-8");
    System.out.println("URI編碼:"+demo);
    demo = URLEncoder.decode(test , "UTF-8");
    System.out.println("URI解碼:"+demo);



    【Blogger】在Blog中貼程式碼

    二版日期:2017/10/10
    初版日期:2013/06/12
    ---------------------------------------------------------------------------------------
    試試這個
    SlidesCodeHighlighter@github
    或是  比較單調的
    http://formatmysourcecode.blogspot.tw/

    ----------------------------我是分隔線---------------------------------------------
    如果把程式碼直接貼到blog上,會造成排版跑掉,增加讀取的困難。
    還好有這個Online syntax highlighting for "Java"


    1. 只要把程式碼貼入textbox中。
    2. 選取想要對應的style以及script語言。
    3. 按下Highlight,產生出的html和css標色語法,記得全選複製貼到blog中。







    【Java】【轉載】 Apache HttpClient 4.x 使用 GET, POST 範例

    在看範例之前先把一些重要連結整理給大家: 
    想知道這次到底更動了哪些東西可以看:Apache HttpClient 首頁
    官方的 Tutorial 在:Apache HttpClient Tutorial 
    而 API DOC、說明文件則在:Apache HttpClient apidocs

    相關的程式碼、jar 檔在:HttpComponents HttpClient 4.0 (GA)
    注意,在寫程式前必需先將四個 jar 檔正確匯入,最後兩個(*)是選用,

    commons-logging-x.x.x.jar
    commons-codec-x.x.x.jar
    httpcore-x.x.x.jar
    httpclient-x.x.x.jar
    apache-mime4j-x.x.x.jar (*)
    httpmime-x.x.x.jar (*)
    說了這麼多,以下是程式的範例,
    第一個是傳回在 google 查詢 httpclient 的結果。
    第二則是傳回台大圖書館查詢 Head First Java 的結果。

    • 實際安裝jar版本:
      • apache-mime4j.jar
      • commons-codec-1.4.jar
      • commons-logging-1.1.1.jar
      • httpclient-4.0.1.jar
      • httpclient-4.1.jar
      • httpcore-4.1.jar
      • httpmime-4.1.jar


    package Crawler;
    
    import java.io.IOException;
    import java.util.ArrayList;
    
    import org.apache.http.HttpStatus;
    
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.utils.URLEncodedUtils;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.util.EntityUtils;
    
    /**
     * Apache HttpClient 4.x 使用 GET, POST 查詢網頁的範例
     * 
     * 
     */
    public class Crawler extends DefaultHttpClient {
    
     public static void main(String[] args) throws IOException {
    
      DefaultHttpClient demo = new DefaultHttpClient();
      demo.getParams().setParameter("http.protocol.content-charset", "UTF-8");
    
      // Get Request Example,取得 google 查詢 httpclient 的結果
      HttpGet httpGet = new HttpGet(http://www.google.com.tw/search?q=httpclinet");
      HttpResponse response = demo.execute(httpGet);
      String responseString = EntityUtils.toString(response.getEntity());
      if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
       // 如果回傳是200 OK 的話才輸出
       System.out.println(responseString);
      } else {
       System.out.println(response.getStatusLine());
      }
     
       // Post Request Example,查詢台大圖書館書籍
       ArrayList<NameValuePair> pairList = new ArrayList<NameValuePair>();
       pairList.add(new BasicNameValuePair("searchtype", "t"));
       pairList.add(new BasicNameValuePair("searchscope", "keyword"));
       pairList.add(new BasicNameValuePair("searcharg", "Head First Java"));
       pairList.add(new BasicNameValuePair("SORT", "D"));
      
       HttpPost httpPost = new
       HttpPost("http://tulips.ntu.edu.tw:1081/search*cht/a?");
       StringEntity entity = new
       StringEntity(URLEncodedUtils.format(pairList, "UTF-8"));
       httpPost.setEntity(entity);
       response = demo.execute(httpPost);
       responseString = EntityUtils.toString(response.getEntity());
       if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
       // 如果回傳是200 OK 的話才輸出
       System.out.println(responseString);
       } else {
       System.out.println(response.getStatusLine());
       }
     }
    }