HttpUrlConnnection

1 從服務(wù)器獲取內(nèi)容

從服務(wù)器獲取內(nèi)容都是以流的方式獲取的,可以獲取字符串,文件,圖片等等,所有的東西都是通過文件流獲取的。
下面是一個從服務(wù)端獲取內(nèi)容的完整步驟
網(wǎng)絡(luò)請求首先需要先開啟權(quán)限

<uses-permission android:name="android.permission.INTERNET" />

進行網(wǎng)絡(luò)請求

//網(wǎng)絡(luò)請求是耗時操作,必須要放在子線程中進行
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 0 網(wǎng)絡(luò)請求時需要捕獲一些異常
                    // 1 創(chuàng)建一個URl對象,傳入url地址
                    URL url=new URL(sourceUrl);
                    // 2 開啟HttpUrlConnection
                    HttpURLConnection connection=(HttpURLConnection)url.openConnection();
                    // 3 設(shè)置請求方式,必須要大寫
                    connection.setRequestMethod("GET");
                    // 4 設(shè)置請求超時時間,單位是毫秒
                    connection.setConnectTimeout(5000);
                    // 5 獲取返回碼
                    int code=connection.getResponseCode();
                    Log.i("test",""+code);
                    // 6 根據(jù)返回碼做相應(yīng)處理
                    if(code==200)
                    {
                        // 7 如果連接正常,則獲取返回的輸入流
                        InputStream in=connection.getInputStream();
                        // 8 對輸入流進行處理
                        // 8.1 初始化一個內(nèi)存輸出流,將輸入流讀出到內(nèi)存中
                        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
                        // 8.2 設(shè)置每次讀入的字節(jié)數(shù)特,1024,每次讀入1kb
                        byte[] bytes=new byte[1024];
                        // 8.3每次讀入的字節(jié)數(shù)
                        int len=-1;
                        while((len=in.read(bytes))!=-1)
                        {
                            // 8.4 將讀入的字節(jié)寫入內(nèi)存中
                            outputStream.write(bytes,0,len);
                        }
                        //8.4 關(guān)閉輸入流,內(nèi)存輸出流不需要關(guān)閉
                        in.close();
                        String output=new String(outputStream.toByteArray());

                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }).start();

上面是一個整個的過程,但是一般網(wǎng)絡(luò)請求,和解析輸入流都會寫成單獨的工具類
將輸入流轉(zhuǎn)換成字符串的工具類

public class MyStreamUtil {
    public static String streamToString(InputStream in)
    {
        byte[] bytes=new byte[1024];
        int len=-1;
        ByteArrayOutputStream out=new ByteArrayOutputStream();
        try {
            while((len=in.read(bytes))>0)
            {
                out.write(bytes,0,len);
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        String string=new String(out.toByteArray());
        return string;
    }
}

網(wǎng)絡(luò)請求的工具類

public class MyHttpUtil {
    public static void getNews(final String url1, final Context context)
    {
        new Thread(new Runnable() {
             @Override
             public void run() {
                 try {
                     URL url=new URL(url1);
                     HttpURLConnection connection=(HttpURLConnection) url.openConnection();
                     connection.setRequestMethod("GET");
                     connection.setConnectTimeout(5000);
                     int code=connection.getResponseCode();
                     if(code==200)
                     {
                         InputStream in=connection.getInputStream();
                         String jsonString=MyStreamUtil.streamToString(in);
                     }

                 } catch (Exception e) {
                     e.printStackTrace();
                 } finally {
                 }
             }
         }).start();
    }
}

在獲取到輸入流之后,可以根據(jù)相應(yīng)的需求進行如下處理
1 如果是json字符串,則將輸入流轉(zhuǎn)換為String類型的字符串,在對json字符串進行解析
2 如果是文件,圖片等類型,則可以不采用內(nèi)存輸出流,直接使用文件流對文件進行存儲,或者使用BitmapFactory工廠類對圖片類型的流進行處理

2 GET方式向服務(wù)器提交數(shù)據(jù)

GET方式提交數(shù)據(jù)只能用于少量數(shù)據(jù)的提交(小于1kb),GET方式其實就是拼接字符串的方式進行數(shù)據(jù)的發(fā)送。
GET方式提交數(shù)據(jù)和上面網(wǎng)絡(luò)請求區(qū)別很少,只需要吧URL改變即可,
服務(wù)器端就可以按照相應(yīng)的處理GET請求的方式接收數(shù)據(jù)

//GET方式的url用問好分開,前面是地址,后面是以key-value方式傳入的數(shù)據(jù)
    //每一對數(shù)據(jù)之間用&分開
    private String name="aaa";
    private int pwd=123;
    private final String getUrl="http://139.129.110.99:8901/test?name="+name+"&pwd="+pwd+"";

3 POST方式提交數(shù)據(jù)
POST方式向服務(wù)端提供數(shù)據(jù)是以流的方式進行的,和GET方式有以下幾點不同
1 url地址中不傳入具體的參數(shù)
2 請求方式變?yōu)镻OST
3 需要設(shè)置請求頭信息
4 通過輸出流的方式將數(shù)據(jù)傳到服務(wù)端
具體過程如下,~~~~~~標出的是和GET方式不同的地方

 //設(shè)置URL地址~~~~~~~~~~~~~~~~~~~~~~~~~~
    private final String postUrl="http://139.129.110.99:8901/posttest";
//設(shè)置傳入的內(nèi)容,key-value形式,每一對參數(shù)之間用&分開
        final String content="name="+name+"&pwd="+pwd;
        //網(wǎng)絡(luò)請求是耗時操作,必須要放在子線程中進行
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 0 網(wǎng)絡(luò)請求時需要捕獲一些異常
                    // 1 創(chuàng)建一個URl對象,傳入url地址
                    URL url=new URL(getUrl);
                    // 2 開啟HttpUrlConnection
                    HttpURLConnection connection=(HttpURLConnection)url.openConnection();
                    // 3 設(shè)置請求方式,必須要大寫~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    connection.setRequestMethod("POST");
                    // 3.1 設(shè)置請求頭信息,Content-Type設(shè)置為application/x-www-form-urlencoded,
                    //代表傳入的內(nèi)容是key-value形式的~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
                    // 3.2 設(shè)置傳入的內(nèi)容的長度,就是content的長度~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    connection.setRequestProperty("Content-Length",""+content.length());
                    // 4 設(shè)置請求超時時間,單位是毫秒
                    connection.setConnectTimeout(5000);
                    // 5設(shè)置允許向服務(wù)端傳數(shù)據(jù)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    connection.setDoOutput(true);
                    //獲取輸出流,并將內(nèi)容傳入服務(wù)端
                    OutPutStream out=connection.getOutputStream();
                    out.write(content.getBytes());
                    out.close();
                    // 6 獲取返回碼
                    int code=connection.getResponseCode();
                    Log.i("test",""+code);
                    // 7 根據(jù)返回碼做相應(yīng)處理
                    if(code==200)
                    {
                        // 8 如果連接正常,則獲取返回的輸入流
                        InputStream in=connection.getInputStream();
                        // 9 對輸入流進行處理
                        // 9.1 初始化一個內(nèi)存輸出流,將輸入流讀出到內(nèi)存中
                        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
                        // 9.2 設(shè)置每次讀入的字節(jié)數(shù)特,1024,每次讀入1kb
                        byte[] bytes=new byte[1024];
                        // 9.3每次讀入的字節(jié)數(shù)
                        int len=-1;
                        while((len=in.read(bytes))!=-1)
                        {
                            // 8.4 將讀入的字節(jié)寫入內(nèi)存中
                            outputStream.write(bytes,0,len);
                        }
                        //9.4 關(guān)閉輸入流,內(nèi)存輸出流不需要關(guān)閉
                        in.close();
                        String output=new String(outputStream.toByteArray());
                        Log.i("test",output);

                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }).start();

關(guān)于Content-Type
1 application/x-www-form-urlencoded
這種方式代表傳入的為key-value形式,content中的內(nèi)容就像上面的程序那樣,服務(wù)端接收時,根據(jù)傳入的值接收數(shù)據(jù)
2 application/json
這種方式代表傳入一個json字符串,content中的內(nèi)容就是一個json字符串,服務(wù)端接收這個字符串,并解析
3 multipart/form-data
這種方式是最復(fù)雜的,代表表單上傳。實際中很少直接用httpUrlConnection實現(xiàn)表單的上傳,一般都用網(wǎng)絡(luò)請求框架去實現(xiàn)
這種方式可以實現(xiàn)單個文件的上傳,多個文件的上傳,帶有文件的表單的上傳(例如完善注冊信息的功能,需要既上傳文字,又上傳圖片)。
步驟
1 模擬http文件上傳的格式
文件上傳時格式如下,這幾個時主要的必須寫的,其他的可以不寫,都會默認填充。

(boundary是自己定義的,什么樣都可以,
  name和filename是自己定義的,其他的都是固定格式。
  無論是否傳文件,name和filename都必須有,后臺接收文件時按照name接收,但是filename也需要存在)
Content-Type: multipart/form-data; boundary=-------zzzz(文件頭,一組文件只要一個)
---------zzzz(每一個文件開始的標志,在boundary前面加2個-)
Content-Disposition: form-data; name="ttt"; filename="123"
第一個空行
第二個空行
abece(這個是名字為ttt的內(nèi)容)
---------zzzz
Content-Disposition: form-data; name="aaa"; filename="aaa.jpg"
第一個空行
第二個空行
圖片文件.
.
.(有多少個文件,就按這種方式寫多少個)
.
.
---------zzzz--(文件尾,一組文件只要一個。結(jié)尾另起新的一行,在前面定義的boundary前后各加2個-)

所以按照上面的格式,就可以自己仿照文件上傳的格式進行文件上傳
下面的代碼在一個表單中上傳了2個文件,如果要繼續(xù)上傳文件,按照格式寫就可以

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //定義自己的boundary
                    String boundary="------zzzz";
                    URL url=new URL(postUrl);
                    HttpURLConnection connection=(HttpURLConnection)url.openConnection();
                    connection.setRequestMethod("POST");
                    connection.setConnectTimeout(5000);
                    connection.setDoOutput(true);
                    //定義文件頭
                    connection.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary);
                    //獲取輸出流
                    OutputStream out=connection.getOutputStream();
                    //第一個文件開始,這個其實是一個key-value對
                    //先定義一個sb字符串,用于傳送第一個文件的各種信息
                    StringBuilder sb=new StringBuilder();
                    //開頭是--------zzzz,然后加\r\n,回車并換行
                    sb.append("--").append(boundary).append("\r\n");
                    //第二行的內(nèi)容,定義好name和filename
                    sb.append("Content-Disposition:form-data;name=\"ttt\";filename=\"ttt1vv.tt\"");
                    //再空兩行
                    sb.append("\r\n\r\n");
                    //第一個文件的內(nèi)容,這里就是一個字符串,所以直接加了進行
                    sb.append("zyl");
                    //將第一個文件的內(nèi)容加入輸出流
                    out.write(sb.toString().getBytes());
                    //在輸出流里加入換行,開始第二個文件,每個文件都需要新起一行
                    out.write("\r\n".getBytes());
                    //第二個文件開始
                    //定義字符串
                    StringBuilder sb1=new StringBuilder();
                    //開頭是--------zzzz,然后加\r\n,回車并換行
                    sb1.append("--"+boundary+"\r\n");
                    //第二行的內(nèi)容,定義好name和filename
                    sb1.append("Content-Disposition:form-data;name=\"aaa\";filename=\"aaavv\"");
                    //空兩行,后面是文件的內(nèi)容
                    sb1.append("\r\n\r\n");
                    //先將這些加入輸出流,因為這個文件的內(nèi)容是一個文件,所以后面直接把內(nèi)容加入輸出流
                    out.write(sb1.toString().getBytes());
                    //獲取到對應(yīng)的問價
                    File file=new File(Environment.getExternalStorageDirectory(),"Pictures");
                    Log.i("test",file.getAbsolutePath());
                    if(!file.exists())
                    {
                        file.mkdirs();
                    }
                    File newFile=new File(file,"b.png");
                    if(!newFile.exists())
                    {
                        newFile.createNewFile();
                    }

                        FileInputStream fileInputStream=new FileInputStream(newFile);
                        int len=-1;
                        byte[] bytes=new byte[1024];
                    //將文件加入輸出流
                        while ((len=fileInputStream.read(bytes))!=-1)
                        {
                            out.write(bytes,0,len);
                        }
                    //定義文件組的結(jié)尾
                    byte[] endData=("\r\n--"+boundary+"--"+"\r\n").getBytes();
                    //將結(jié)尾加入輸出流
                    out.write(endData);
                    //關(guān)閉輸出流,輸出流被上傳到服務(wù)器
                    out.close();
                    //后面再開始接收服務(wù)器返回的內(nèi)容,這里就不繼續(xù)寫了
                    Log.i("test",""+connection.getResponseCode());
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                    Log.i("test","0");
                }catch (IOException e)
                {
                    e.printStackTrace();
                    Log.i("test","1");
                }
            }
        }).start();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,836評論 18 139
  • 國家電網(wǎng)公司企業(yè)標準(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,079評論 6 13
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,180評論 4 61
  • 昨天在貓叔哪里看到這個視頻。 據(jù)說發(fā)布不到10天就有1億人瀏覽。 覺得很不錯所以分享給大家...
    得一_閱讀 1,228評論 1 1
  • 余月流云,暖風熏樹,一碧溪漾。漸透枝陰,稍斜欲倩,縷縷塵囂上。 惠和汀榭,峋巖漏語,惹絮柳蓬蒲放。曉南堤、池蛙不懼...
    銓齋閱讀 312評論 0 13