Java代碼發(fā)送Http的GET和POST請求

這篇也是接上一篇猬错,發(fā)送請求的url就是前面創(chuàng)建的java web工程中有的饥漫。

1犀变、HTTP中GET和POST的區(qū)別

首先要了解下GET和POST的區(qū)別妹孙。
HTTP定義了4種與服務(wù)器交互方法:GET,POST获枝,PUT蠢正,DELETE。URL全稱是資源描述符映琳,可以這樣認為:一個URL地址机隙,它用于描述一個網(wǎng)絡(luò)上的資源蜘拉,而HTTP中的GET萨西,POST,PUT旭旭,DELETE可以理解為就對應(yīng)著對這個資源的查谎脯,改,增持寄,刪4個操作源梭。GET一般用于獲取/查詢資源信息,而POST一般用于更新資源信息稍味。GET和POST的區(qū)別主要從以下幾個方面理解:

  • 用途
    根據(jù)HTTP規(guī)范废麻,GET用于信息獲取,用于獲取信息而非修改信息模庐。GET請求一般不應(yīng)產(chǎn)生副作用烛愧。它僅僅是獲取資源信息,就像數(shù)據(jù)庫查詢一樣,不會修改怜姿,增加數(shù)據(jù)慎冤,不會影響資源的狀態(tài)。對同一URL的多個請求應(yīng)該返回同樣的結(jié)果沧卢。 POST可能修改變服務(wù)器上的資源的請求蚁堤。
  • 請求數(shù)據(jù)的傳遞方式
    GET請求的數(shù)據(jù)會附在URL之后(就是把數(shù)據(jù)放置在HTTP協(xié)議頭中),以?分割URL和傳輸數(shù)據(jù)但狭,參數(shù)之間以&相連披诗,如:buy.jsp?product=apple&amount=1111&verify=%E4%BD%A0%E5%A5%BD。如果數(shù)據(jù)是英文字母或者數(shù)字立磁,原樣發(fā)送藤巢,如果是空格,轉(zhuǎn)換為+息罗,如果是中文或者其他字符掂咒,則直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD迈喉,其中%XX中的XX為該符號以16進制表示的ASCII绍刮。而POST把提交的數(shù)據(jù)則放置在是HTTP包的包體中
  • 提交數(shù)據(jù)的大小限制
    GET方式提交的數(shù)據(jù)最多只能是1024字節(jié)(GET請求中參數(shù)是附在url后面的挨摸,實際上這個長度是url長度的要求)孩革。理論上POST沒有限制,可傳較大量的數(shù)據(jù)得运。這一點可以先簡單這么理解膝蜈。
  • 安全性
    POST的安全性要比GET的安全性高。比如熔掺,通過GET提交數(shù)據(jù)饱搏,用戶名和密碼將明文出現(xiàn)在URL上。
  • 常見場景
    在FORM表單中置逻,Method默認為"GET"推沸。在瀏覽器地址欄中輸入url發(fā)生請求都是GET,如果要發(fā)送POST請求就需要通過提交form表單來完成券坞。

2鬓催、Java代碼發(fā)送GET和POST請求

Java中應(yīng)該有好多種方式,可以發(fā)送GET和POST請求恨锚。這里介紹兩種:通過HttpURLConnection和通過Apache HttpClient庫宇驾。

2.1 通過HttpURLConnection發(fā)送GET和POST請求

這種方式基本上算是java原生的,不需要導入任何jar包依賴就可以運行猴伶。代碼如下:

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by chengxia on 2018/12/4.
 */
public class HttpURLConnectionDemo {
    public String doPost(String URL){
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        HttpURLConnection conn = null;
        try{
            URL url = new URL(URL);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            //發(fā)送POST請求必須設(shè)置為true
            conn.setDoOutput(true);
            conn.setDoInput(true);
            //設(shè)置連接超時時間和讀取超時時間
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(10000);
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Accept", "application/json");
            //獲取輸出流
            out = new OutputStreamWriter(conn.getOutputStream());
            String jsonStr = "{\"qry_by\":\"name\", \"name\":\"Tim\"}";
            out.write(jsonStr);
            out.flush();
            out.close();
            //取得輸入流课舍,并使用Reader讀取
            if (200 == conn.getResponseCode()){
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
                String line;
                while ((line = in.readLine()) != null){
                    result.append(line);
                    System.out.println(line);
                }
            }else{
                System.out.println("ResponseCode is an error code:" + conn.getResponseCode());
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(out != null){
                    out.close();
                }
                if(in != null){
                    in.close();
                }
            }catch (IOException ioe){
                ioe.printStackTrace();
            }
        }
        return result.toString();
    }

    public String doGet(String URL){
        HttpURLConnection conn = null;
        InputStream is = null;
        BufferedReader br = null;
        StringBuilder result = new StringBuilder();
        try{
            //創(chuàng)建遠程url連接對象
            URL url = new URL(URL);
            //通過遠程url連接對象打開一個連接菌瘫,強轉(zhuǎn)成HTTPURLConnection類
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            //設(shè)置連接超時時間和讀取超時時間
            conn.setConnectTimeout(15000);
            conn.setReadTimeout(60000);
            conn.setRequestProperty("Accept", "application/json");
            //發(fā)送請求
            conn.connect();
            //通過conn取得輸入流,并使用Reader讀取
            if (200 == conn.getResponseCode()){
                is = conn.getInputStream();
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                String line;
                while ((line = br.readLine()) != null){
                    result.append(line);
                    System.out.println(line);
                }
            }else{
                System.out.println("ResponseCode is an error code:" + conn.getResponseCode());
            }
        }catch (MalformedURLException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(br != null){
                    br.close();
                }
                if(is != null){
                    is.close();
                }
            }catch (IOException ioe){
                ioe.printStackTrace();
            }
            conn.disconnect();
        }
        return result.toString();
    }


    public static void main(String[] args) throws Exception {
        HttpURLConnectionDemo http = new HttpURLConnectionDemo();
        
        System.out.println("Testing 1 - Do Http GET request");
        http.doGet("http://localhost:8080");

        System.out.println("\nTesting 2 - Do Http POST request");
        http.doPost("http://localhost:8080/json");

    }

}

運行的輸出如下:

Testing 1 - Do Http GET request


<html>
  <head>
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello Word!</h1>
  </body>
</html>

Testing 2 - Do Http POST request
[{name:'Kobe', team:‘Lakers’},{name:'Tim', team:‘Spurs’}]

Process finished with exit code 0

從這個例子的代碼中就可以看出布卡,GET請求向服務(wù)器發(fā)送的數(shù)據(jù)雨让,都放在url中,這樣在發(fā)送請求是不用向請求正文中寫入數(shù)據(jù)忿等。而POST請求在發(fā)送時栖忠,必須先將發(fā)送的數(shù)據(jù),寫入到請求正文中贸街。下面的apache httpclient實現(xiàn)中庵寞,也能看出這個區(qū)別。

2.2 通過Apache HttpClient發(fā)送GET和POST請求

這里需要用到Apache HttpClient的依賴包薛匪,所以要先去官網(wǎng)下載依賴的jar包:

Apache官網(wǎng)下載依賴jar包

解壓之后捐川,將lib目錄下所有的jar包文件,導入到工程的依賴目錄(我曾經(jīng)天真的以為只需要一個httpclient-4.5.6.jar逸尖,然而在編譯時各種報錯古沥,全部導入到就好了):
下載的jar包解壓之后

全部導入到工程的依賴目錄中

最后,Java代碼如下:

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;

/**
 * Created by chengxia on 2018/12/5.
 */
public class ApacheHttpClientDemo {
    public String doGet(String url){
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        String result = "";
        try{
            //通過默認配置創(chuàng)建一個httpClient實例
            httpClient = HttpClients.createDefault();
            //創(chuàng)建httpGet遠程連接實例
            HttpGet httpGet = new HttpGet(url);
            //httpGet.addHeader("Connection", "keep-alive");
            //設(shè)置請求頭信息
            httpGet.addHeader("Accept", "application/json");
            //配置請求參數(shù)
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(35000) //設(shè)置連接主機服務(wù)超時時間
                    .setConnectionRequestTimeout(35000)//設(shè)置請求超時時間
                    .setSocketTimeout(60000)//設(shè)置數(shù)據(jù)讀取超時時間
                    .build();
            //為httpGet實例設(shè)置配置
            httpGet.setConfig(requestConfig);
            //執(zhí)行g(shù)et請求得到返回對象
            response = httpClient.execute(httpGet);
            //通過返回對象獲取返回數(shù)據(jù)
            HttpEntity entity = response.getEntity();
            //通過EntityUtils中的toString方法將結(jié)果轉(zhuǎn)換為字符串娇跟,后續(xù)根據(jù)需要處理對應(yīng)的reponse code
            result = EntityUtils.toString(entity);
            System.out.println(result);

        }catch (ClientProtocolException e){
            e.printStackTrace();
        }catch (IOException ioe){
            ioe.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //關(guān)閉資源
            if(response != null){
                try {
                    response.close();
                }catch (IOException ioe){
                    ioe.printStackTrace();
                }
            }
            if(httpClient != null){
                try{
                    httpClient.close();
                }catch (IOException ioe){
                    ioe.printStackTrace();
                }
            }
        }
        return result;
    }
    public String doPost(String url){
        //創(chuàng)建httpClient對象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String result = "";
        try{
            //創(chuàng)建http請求
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("Content-Type", "application/json");
            //創(chuàng)建請求內(nèi)容
            String jsonStr = "{\"qry_by\":\"name\", \"name\":\"Tim\"}";
            StringEntity entity = new StringEntity(jsonStr);
            httpPost.setEntity(entity);
            response = httpClient.execute(httpPost);
            result = EntityUtils.toString(response.getEntity(),"utf-8");
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //關(guān)閉資源
            if(response != null){
                try {
                    response.close();
                }catch (IOException ioe){
                    ioe.printStackTrace();
                }
            }
            if(httpClient != null){
                try{
                    httpClient.close();
                }catch (IOException ioe){
                    ioe.printStackTrace();
                }
            }
        }
        return result;
    }
    public static void main(String[] args) throws Exception {
        ApacheHttpClientDemo http = new ApacheHttpClientDemo();

        System.out.println("Testing 1 - Do Http GET request");
        http.doGet("http://localhost:8080");

        System.out.println("\nTesting 2 - Do Http POST request");
        http.doPost("http://localhost:8080/json");

    }

}

由于是向相同的url發(fā)送請求岩齿,這個例子的輸出和前面的例子是一樣的。

參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市岗憋,隨后出現(xiàn)的幾起案子肃晚,更是在濱河造成了極大的恐慌,老刑警劉巖澜驮,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陷揪,死亡現(xiàn)場離奇詭異惋鸥,居然都是意外死亡杂穷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門卦绣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耐量,“玉大人,你說我怎么就攤上這事滤港±妊眩” “怎么了趴拧?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長山叮。 經(jīng)常有香客問我著榴,道長,這世上最難降的妖魔是什么屁倔? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任脑又,我火速辦了婚禮,結(jié)果婚禮上锐借,老公的妹妹穿的比我還像新娘问麸。我一直安慰自己,他們只是感情好钞翔,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布严卖。 她就那樣靜靜地躺著,像睡著了一般布轿。 火紅的嫁衣襯著肌膚如雪哮笆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天汰扭,我揣著相機與錄音疟呐,去河邊找鬼。 笑死东且,一個胖子當著我的面吹牛启具,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播珊泳,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鲁冯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了色查?” 一聲冷哼從身側(cè)響起薯演,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秧了,沒想到半個月后跨扮,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡验毡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年衡创,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晶通。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡璃氢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狮辽,到底是詐尸還是另有隱情一也,我是刑警寧澤巢寡,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站椰苟,受9級特大地震影響抑月,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舆蝴,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一爪幻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧须误,春花似錦挨稿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至祭椰,卻和暖如春臭家,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背方淤。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工钉赁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人携茂。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓你踩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讳苦。 傳聞我的和親對象是個殘疾皇子带膜,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容