[Java]開(kāi)發(fā)安卓询张,你得掌握的Java知識(shí)14——網(wǎng)絡(luò)數(shù)據(jù)傳輸

0.前言

  • 上面兩篇文章,
    講解了網(wǎng)絡(luò)中浙炼,底層的數(shù)據(jù)傳輸?shù)脑恚⊿ocket)

  • 本文則著重講解實(shí)際情況中份氧,我們?nèi)绾问褂肑ava進(jìn)行數(shù)據(jù)的傳輸(上傳、下載等)

  • 若想要了解“類(lèi)”等其他主要知識(shí)弯屈,可以去看前面的文章

  • 由于最終目的是要開(kāi)發(fā)安卓app蜗帜,
    因此這里使用的IDE是AS(Android Studio)
    (不會(huì)使用的可以參考下面這篇文章中的例子)
    [Java]開(kāi)發(fā)安卓,你得掌握的Java知識(shí)2

1.準(zhǔn)備工作

在讀本文前资厉,你需要做好以下準(zhǔn)備:

  • (1)要配置好apache服務(wù)器
  • (2)電腦中配置了php钮糖,可以寫(xiě)php代碼
  • (3)大致了解前后端交互
  • (4)可以的話,最好去了解一下html的表單<form>
  • 推薦新手使用wampserver 64酌住,
    它集成了php店归、apache、MYSQL數(shù)據(jù)庫(kù)
  • 直接安裝酪我、運(yùn)行wampserver 64消痛,就可以免去配置php、apache的復(fù)雜操作都哭。

2.基礎(chǔ)知識(shí)講解


URL的一些奧秘

  • url就是我們?cè)诘刂窓谳斎氲木W(wǎng)址
    一般我們可能只會(huì)注意到www.xxx.com這部分秩伞,
    后面的內(nèi)容,外行人可能以為是亂碼
  • 其實(shí)欺矫,url的每一個(gè)部分都有它對(duì)應(yīng)的意思纱新,只是我們未必能知道而已
  • www.xxx.com這部分叫域名,其實(shí)是與ip地址有映射關(guān)系的字符串穆趴,我們>訪問(wèn)的所有網(wǎng)頁(yè)脸爱,其實(shí)都是接入網(wǎng)絡(luò)中的某臺(tái)計(jì)算機(jī)中的內(nèi)容(這些計(jì)算機(jī)一般叫做服務(wù)器)

  • 域名后面的那些用斜杠隔開(kāi)的,其實(shí)是對(duì)應(yīng)的文件夾未妹,我們?cè)L問(wèn)的網(wǎng)頁(yè)簿废,就是ip地址所指向的計(jì)算機(jī)中空入,某個(gè)指定文件夾下面的某個(gè)html文件(當(dāng)然可能是jsp什么的)

  • 如果看到有?name=jack&age=12之類(lèi)的格式,其實(shí)就是向?qū)?yīng)的文件傳參數(shù)族檬,實(shí)際上就是在說(shuō):
    name = jack , age = 12
    把這兩個(gè)參數(shù)傳過(guò)去

  • 比如這一點(diǎn)可以在微博中有一定作用


  • is_hot=1表示按照微博的火熱程度來(lái)排序
    如果改成is_all=1歪赢,那么就會(huì)按照時(shí)間排序,這一點(diǎn)十分有用

Get與Post

  • get與post是兩種傳遞數(shù)據(jù)的方式单料,他們最主要的區(qū)別在于:
get:

①傳遞的數(shù)據(jù)會(huì)出現(xiàn)在地址欄中(就是上面所說(shuō)的?name=jack&age=12)
②傳遞的數(shù)據(jù)不能太多
③由于數(shù)據(jù)會(huì)出現(xiàn)在地址欄埋凯,因此不安全
④雖然不安全,但是我們可以通過(guò)修改地址欄的參數(shù)傳遞扫尖,來(lái)改變一些東西(比如上面微博的那個(gè)例子is_all與is_hot)

post:

①傳遞的數(shù)據(jù)會(huì)出現(xiàn)在地址欄中
②由于數(shù)據(jù)會(huì)出現(xiàn)在地址欄递鹉,因此安全
③可以一次傳遞大量數(shù)據(jù)
④代碼編寫(xiě)比get方法略微復(fù)雜一點(diǎn)

PHP簡(jiǎn)單語(yǔ)法:

  • 變量的定義:
    $name = "jack"

  • 輸出/返回內(nèi)容:
    echo $name;或者echo "jack"

  • 變量的獲取:
    $age = $_GET["age"];
    注意:

  • 這里的GET表示是用GET方法傳遞數(shù)據(jù)藏斩,因此要用$_GET來(lái)獲取穿過(guò)來(lái)的數(shù)據(jù)

  • "age"是傳遞數(shù)據(jù)的時(shí)候指定的名字躏结,如果是用html傳遞的話,就是寫(xiě)在標(biāo)簽中的name(這個(gè)name是標(biāo)簽的一個(gè)參數(shù))
    <input type="text" name="age">

3.具體實(shí)現(xiàn)方法

本文會(huì)wampserver64來(lái)使用php狰域、apache服務(wù)器

第一步

先寫(xiě)一個(gè)php文件媳拴,來(lái)作為接受、返回?cái)?shù)據(jù)

<?php 
    $name = $_POST["fname"];
    $age = $_POST["age"];
    echo $name." ".$age."歲"; 
?> 
  • 簡(jiǎn)單來(lái)說(shuō)就是定義了兩個(gè)變量name和age
    然后返回
    $name $age歲

第二步

把這個(gè)php文件放在wamp64\www下面
www是wampserver這個(gè)集成軟件的根目錄
默認(rèn)的apache服務(wù)器的根目錄在htdocs

第三步

在java程序中書(shū)寫(xiě)傳遞數(shù)據(jù)的函數(shù)
(我知道代碼很長(zhǎng)很?chē)樔苏桌溃a后面會(huì)有逐句分析)

public static void post() throws IOException {
        //1.創(chuàng)建URL對(duì)象
        URL url = new URL("http://127.0.0.1/AndroidTest/test1.5.php");
        //2.創(chuàng)建HttpURLConnection對(duì)象
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        //3.設(shè)置請(qǐng)求方式為post
        connection.setRequestMethod("POST");
        //設(shè)置有輸出流(說(shuō)明需要上傳屈溉,默認(rèn)值為false)
        connection.setDoOutput(true);
        //設(shè)置輸入流,默認(rèn)為true(服務(wù)器肯定會(huì)返回?cái)?shù)據(jù)
        connection.setDoInput(true);
        //4.準(zhǔn)備上傳的數(shù)據(jù)
        String data = "fname=jack&age=12";

        //5.開(kāi)始上傳 要得到輸出流對(duì)象(不斷向服務(wù)器輸出)
        OutputStream os = connection.getOutputStream();
        //data是字符串抬探,要轉(zhuǎn)換為字節(jié)
        os.write(data.getBytes());
        os.flush();//寫(xiě)完了

        //6,接收服務(wù)器端返回的數(shù)據(jù)
        InputStream is = connection.getInputStream();
        byte[] buf = new byte[1024];
        int len;
        while ((len = is.read(buf)) != -1) {
            System.out.println(new String(buf,0,len));
        }
    }

POST請(qǐng)求方式

  • 首先子巾,我們實(shí)際用java在網(wǎng)絡(luò)中傳遞數(shù)據(jù),不會(huì)像之前那樣直接用Socket小压,原因是:
    Socket有局限性线梗,我們只能在Socket中放ip地址和端口,但是
    無(wú)法讓socket知道訪問(wèn)該ip地址中的哪個(gè)文件

  • 所以我們用的是封裝了Socket的URL類(lèi)來(lái)實(shí)現(xiàn)數(shù)據(jù)傳遞怠益,
    URL的構(gòu)造參數(shù)中放的是欲訪問(wèn)的網(wǎng)址

  • 使用HTTPURLConnection的原因是要設(shè)置請(qǐng)求方式和輸出流
    因?yàn)?strong>請(qǐng)求方式默認(rèn)為GET仪搔,所以post才需要設(shè)置請(qǐng)求方式

  • String data就是想要發(fā)送給指定文件的內(nèi)容,雖然是post方式蜻牢,但是也是要按照類(lèi)似get方式來(lái)寫(xiě)(只是開(kāi)頭沒(méi)有?)

  • 輸出流用的是字節(jié)流OutputStream烤咧,
    getBytes()可以將字符串變?yōu)樽止?jié)數(shù)組

  • 讀取返回的內(nèi)容用的是InputStream,InputStream后面幾行都是常規(guī)操作抢呆,如果不熟悉的可以去看之前的文章:
    [Java]開(kāi)發(fā)安卓煮嫌,你得掌握的Java知識(shí)9

執(zhí)行結(jié)果:(要找一個(gè)main函數(shù)調(diào)用post())


GET請(qǐng)求方式

java代碼差不多(要簡(jiǎn)單一些):

public static void getParams() throws IOException {
        String path = "http://127.0.0.1/AndroidTest/test.php?fname=jack&age=12";
        URL url = new URL(path);

        //1.5.指明請(qǐng)求方式,默認(rèn)為get

        //2.獲取連接的對(duì)象(URLConnection封裝了socket抱虐,socket可以做的昌阿,URLConnection都可以做)
        URLConnection connection = url.openConnection();

        //接受服務(wù)器端的數(shù)據(jù)
        InputStream is = connection.getInputStream();
        byte[] buf = new byte[1024];
        int len;
        while ((len = is.read(buf)) != -1) {
            System.out.println(new String(buf,0,len));
        }
    }

主要區(qū)別在于:

  • 將要傳遞的數(shù)據(jù)放到了path中,不需要額外傳數(shù)據(jù)

  • 不需要去設(shè)置請(qǐng)求方式

  • php文件中的 _POST要改為_(kāi)GET

傳遞文件

public static void getImage() throws IOException {
        //URL
        URL url = new URL("http://localhost/1.jpg");

        //獲取與服務(wù)器連接的對(duì)象
        URLConnection connection = url.openConnection();

        //讀取下載的內(nèi)容 - 獲取輸入流
        InputStream is = connection.getInputStream();

        //創(chuàng)建文件保存的位置,路徑自己定義
        String desPath ="D:\\AndroidStudioProjects\\AndroidCourse\\JavaCourse1Day1\\course1day1\\src\\main\\java\\course1day14\\1.jpg";
        FileOutputStream fos = new FileOutputStream(desPath);

        //具體的下載操作
        byte[] buf = new byte[1024];
        int len;
        while ((len = is.read(buf)) != -1) {
            fos.write(buf,0,len);
        }
    }
  • URL宝泵、URLConnection的操作和上面的POST、GET一樣

-下面的InputStream到最后的while那部分代碼轩娶,
就是經(jīng)典的文件的拷貝儿奶,先用InputStream讀取文件到緩存,再用FileOutputStream將文件從緩存中讀出
只不過(guò)這次是從服務(wù)器中把文件拷貝到本地

  • byte[]是字節(jié)數(shù)組鳄抒,新手可能沒(méi)見(jiàn)過(guò)闯捎,它的目的就是在讀取文件時(shí),找一個(gè)地方放你要讀取到的東西的一部分许溅,然后將這次讀到的內(nèi)容寫(xiě)到硬盤(pán)中瓤鼻,要反復(fù)多次這樣的操作,直至將整個(gè)文件拷貝完
    (當(dāng)然贤重,每次讀寫(xiě)的單位還是一個(gè)字節(jié)茬祷,只是字節(jié)數(shù)組能一次性放下1024個(gè)字節(jié)而已)

4.總結(jié)

(1)本文講解了實(shí)際情況中,如何實(shí)現(xiàn)網(wǎng)絡(luò)中的數(shù)據(jù)傳遞并蝗,比起使用底層的socket進(jìn)行交互祭犯,封裝好的URL更加方便
(2)雖然訪問(wèn)服務(wù)器可以使用URL這種封裝好的類(lèi),但是數(shù)據(jù)的讀寫(xiě)依然要使用InputStream和OutputStream這些類(lèi)滚停,因此即使看起來(lái)很復(fù)雜沃粗,也有必要多多熟悉字節(jié)、字符輸入輸出流的使用方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末键畴,一起剝皮案震驚了整個(gè)濱河市最盅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌起惕,老刑警劉巖涡贱,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異惹想,居然都是意外死亡盼产,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)勺馆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)戏售,“玉大人,你說(shuō)我怎么就攤上這事草穆」嘣郑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵悲柱,是天一觀的道長(zhǎng)锋喜。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么嘿般? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任段标,我火速辦了婚禮,結(jié)果婚禮上炉奴,老公的妹妹穿的比我還像新娘逼庞。我一直安慰自己,他們只是感情好瞻赶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布赛糟。 她就那樣靜靜地躺著,像睡著了一般砸逊。 火紅的嫁衣襯著肌膚如雪璧南。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天师逸,我揣著相機(jī)與錄音司倚,去河邊找鬼。 笑死篓像,一個(gè)胖子當(dāng)著我的面吹牛对湃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播遗淳,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼拍柒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了屈暗?” 一聲冷哼從身側(cè)響起拆讯,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎养叛,沒(méi)想到半個(gè)月后种呐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弃甥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年爽室,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淆攻。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阔墩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瓶珊,到底是詐尸還是另有隱情啸箫,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布伞芹,位于F島的核電站忘苛,受9級(jí)特大地震影響蝉娜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扎唾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一召川、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胸遇,春花似錦荧呐、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)获雕。三九已至薄腻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間届案,已是汗流浹背庵楷。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留楣颠,地道東北人尽纽。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像童漩,于是被迫代替她去往敵國(guó)和親弄贿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

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

  • 一矫膨、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 5,746評(píng)論 0 10
  • 前言 多年以前自學(xué)Java差凹,在本地做了一些筆記。最近幾年流行播客侧馅,一方面防止丟失危尿,一方面可以幫助其他小伙伴...
    chaohx閱讀 1,033評(píng)論 0 3
  • 概要 64學(xué)時(shí) 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,197評(píng)論 0 3
  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類(lèi): pyspark.sql...
    mpro閱讀 9,456評(píng)論 0 13
  • 個(gè)人入門(mén)學(xué)習(xí)用筆記、不過(guò)多作為參考依據(jù)馁痴。如有錯(cuò)誤歡迎斧正 目錄 簡(jiǎn)書(shū)好像不支持錨點(diǎn)谊娇、復(fù)制搜索(反正也是寫(xiě)給我自己看...
    kirito_song閱讀 2,472評(píng)論 1 37