1. 程式人生 > >【Android】Android與伺服器互動 POST上傳多個圖片檔案、文字內容 GET下載圖片

【Android】Android與伺服器互動 POST上傳多個圖片檔案、文字內容 GET下載圖片

這裡伺服器端採用的是php解析內容

HTTP請求

  HTTP 請求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 這幾種。用於資料互動的最基本方法一般為GET、POST、PUT、DELETE。對應著資源的查,改,增,刪4個操作。
  常用的是GET 和 POST,GET一般用於獲取/查詢資源資訊,而POST一般用於更新資源資訊。
  根據HTTP規範,GET用於資訊獲取,而且應該是安全的和冪等的。所謂安全的意味著該操作用於獲取資訊而非修改資訊。換句話說,GET 請求一般不應產生副作用。就是說,它僅僅是獲取資源資訊,就像資料庫查詢一樣,不會修改,增加資料,不會影響資源的狀態。
  根據HTTP規範,POST表示可能修改變伺服器上的資源的請求。


  早期的Web MVC框架設計者們並沒有有意識地將URL當作抽象的資源來看待和設計,所以導致一個比較嚴重的問題是傳統的Web MVC框架基本上都只支援GET和POST兩種HTTP方法,而不支援PUT和DELETE方法。
  我們再來看看GET和POST的區別:
  GET請求的資料會附在URL之後(就是把資料放置在HTTP協議頭中),以?分割URL和傳輸資料,引數之間以&相連,如果資料是英文字母/數字,原樣傳送,如果是空格,轉換為+,如果是中文/其他字元,則直接把字串用BASE64加密。
  POST把提交的資料則放置在是HTTP包的包體中。
  

GET下載內容

這裡是一個android端下載伺服器上的一個圖片檔案,可以看到非常簡單,這裡url可以換成你們所需要的內容,我這裡是一個本地伺服器上的圖片。

public void  download_headportrait(){
        final String url_head="http://172.16.1.93:80/ActivitySharing/upload_headportrait/";
        final String pic_name=map.get("user_account")+".png";
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //這裡的url是你需要下載的檔案的路徑
URL url = new URL(url_head+pic_name); //建立一個HttpURLConnection的連結物件 HttpURLConnection httpURLConnection =(HttpURLConnection)url.openConnection(); //設定方式為GET 方式 這裡 如果不設定也行 因為HttpURLConnection 預設為GET方式 httpURLConnection.setRequestMethod("GET"); //獲取迴應碼 int statusCode = httpURLConnection.getResponseCode(); //獲取所下載檔案的InputStream物件 if (statusCode == 200) { InputStream inputStream=httpURLConnection.getInputStream(); Bitmap bitmap= BitmapFactory.decodeStream(inputStream); //返回下載檔案的InputStream物件 //這裡的bitmap就是所需要下載的圖片,然後在進行後續操作 } }catch (Exception e){ Log.getStackTraceString(e); } } }).start(); }

POST上傳

  HTTP 協議是以 ASCII 碼傳輸,建立在 TCP/IP 協議之上的應用層規範。規範把 HTTP 請求分為三個部分:狀態行、請求頭、訊息主體。
  協議規定 POST 提交的資料必須放在訊息主體(entity-body)中,但協議並沒有規定資料必須使用什麼編碼方式。實際上,開發者完全可以自己決定訊息主體的格式,只要最後傳送的 HTTP 請求滿足上面的格式就可以。

  application/x-www-form-urlencoded
  瀏覽器的原生 form 表單,如果不設定 enctype 屬性,便會自動是這種。提交的資料按照 key1=val1&key2=val2 的方式進行編碼,在伺服器端(例如php)直接從$_POST['key1']$_POST['key2']中就可以取出來。
  
  application/json
  提交的內容以json格式編碼,伺服器端(php)可以通過json_decode()進行解碼得到資訊。json格式個人覺得是非常好用的格式,我一般傳送一些簡單的請求與訪問和伺服器端的回覆響應都採用json格式,條理會很清晰。
  json格式就是以鍵值對存放的,用{}包裹起來,例如

{
    "title":"hello world!",
    "message":"1234"
}

其中,裡面的值也可以是json格式

{
    "title":{
             "h1":"ttt",
             "h2":"biubiubiu"   
            },
    "message":"1234"
}

這裡我們看一個POST json格式內容以達到賬號登陸的例子
首先是android端

 new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    URL url = new URL(url_login);
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    //設定請求方式
                    httpURLConnection.setRequestMethod("POST");
                    // 設定是否向httpUrlConnection輸出,因為這個是post請求,引數要放在
                    // http正文內,因此需要設為true, 預設情況下是false;
                    httpURLConnection.setDoOutput(true);
                    // 設定是否從httpUrlConnection讀入,預設情況下是true;
                    httpURLConnection.setDoInput(true);
                    // Post 請求不能使用快取
                    httpURLConnection.setUseCaches(false);
                    // 設定請求的超時時間
                    httpURLConnection.setReadTimeout(5000);
                    httpURLConnection.setConnectTimeout(5000);

                    httpURLConnection.setRequestProperty("Content-type", "application/json;charset=utf-8");
                    httpURLConnection.connect();

                    //POST請求
                    OutputStream out = httpURLConnection.getOutputStream();
                    JSONObject obj = new JSONObject();
                    obj.put("user_account", account);
                    obj.put("user_password", password);
                    Log.v("TAG", obj.toString());
                    out.write(obj.toString().getBytes());
                    out.flush();
                    out.close();

                    //讀取響應
                    BufferedReader reader = new BufferedReader(new InputStreamReader(
                            httpURLConnection.getInputStream()));
                    String lines;
                    StringBuffer sb = new StringBuffer();
                    while ((lines = reader.readLine()) != null) {
                        lines = new String(lines.getBytes(), "utf-8");
                        sb.append(lines);
                    }
                    Log.v("TAG", sb.toString());
                    reader.close();
                    httpURLConnection.disconnect();

                    //接收完畢
                    JSONObject response = new JSONObject(sb.toString());
                    Message msg = Message.obtain();
                    msg.obj = response;
                    msg.what = method;
                    // 傳送這個訊息到訊息佇列中
                    handler.sendMessage(msg);

                } catch (Exception e) {
                    Log.getStackTraceString(e);
                }
            }
        }).start();

這裡我用一個handler去傳送最終伺服器端返回的json格式響應

伺服器端程式碼如下(PHP)

<?php

    $response =array();
    //注意application/json方式POST的內容需要使用file_get_contents("php://input")從源流中獲取
    $v=json_decode(file_get_contents("php://input"),true);

    if (isset($v['user_account'])  && isset($v['user_password'])) {
        require_once __DIR__ . '/db_connect.php';
         // 連線資料庫
        $db = new DB_CONNECT();
        $mysqli= $db->connect();

        if ($mysqli){
            $user_account=$v['user_account'];
            $user_password=$v['user_password'];

            //mysqli_query($mysqli,"set character set 'gbk'");   //避免中文亂碼字元轉換
            //mysqli_query($mysqli,"set character set 'utf8'");   // PHP 檔案為 utf-8 格式時使用

            $result=mysqli_query($mysqli,"SELECT *FROM activitysharing_user
                WHERE user_account='$user_account' AND user_password='$user_password'");


            if (mysqli_num_rows($result)>0){
                while( $row = mysqli_fetch_array($result)){

                $response["result"]="SUCCEED";
                $response["message"]="login successful";

                $response["user_account"]=$row['user_account'];
                $response["user_password"]=$row['user_password'];
                $response["nickname"]=$row['nickname'];
                $response["gender"]=$row['gender'];
                $response["introduction"]=$row['introduction'];
                $response["article"]=$row['article'];
                $response["subscription"]=$row['subscription'];
                $response["favorite"]=$row['favorite'];
                $response["comment"]=$row['comment'];
                echo json_encode($response);
                }

            }//賬號密碼不存在
            else {
            $response["result"]="FALED_AP";
            $response["message"]="account or password does not exist";
            echo json_encode($response);
            }
        }
        //連線資料庫失敗
        else{
            $response["result"]="FALED";
            $response["message"]="connect database failed";
        echo json_encode($response);
        }
    }
    //賬號密碼為空
    else {
        $response["result"]="FALED";
        $response["message"]="Account or Password dismiss";
        echo json_encode($response);
    }

?>

注意application/json方式POST的內容需要使用file_get_contents("php:input")從源流中獲取

  multipart/form-data
  這種方式一般用於上傳檔案,這種方式對請求的格式有著嚴格的要求,首先來看下一個請求體的例子。
  

[email protected]*_*@EmPty_xL--------
Content-Disposition: form-data; name="title"

hello world!
[email protected]*_*@EmPty_xL--------
Content-Disposition: form-data; name="contentimage1";filename="ssssssss1.png"

������JFIF����������������C������C����+�s��3�  **這裡是圖片1的內容有很多行我刪掉了大部分**����&i�g����O���[email protected]��
[email protected]*_*@EmPty_xL--------
Content-Disposition: form-data; name="contentimage2";filename="ssssssss2.png"

������JFIF����������������C������C����|C�1�m����**這裡是圖片2的內容有很多行我刪掉了大部分**i����s�w����:����
[email protected]*_*@EmPty_xL--------
Content-Disposition: form-data; name="text"

<b>lalala<br><div style="text-align: left;"><img src="ssssssss1.png" alt="picture"></div></b><div style="text-align: right;"><img src="ssssssss2.png" alt="picture"></div>
[email protected]*_*@EmPty_xL--------
Content-Disposition: form-data; name="user_account"

ssssssss
[email protected]*_*@EmPty_xL--------
Content-Disposition: form-data; name="imagenumber"

2
[email protected]*_*@EmPty_xL----------

如上面這段程式碼,首先生成了String boundary = "[email protected]*_*@EmPty_xL--------";作為分界標誌,這個標誌可以你自己隨便設定,儘量長且複雜,以免與正文內容衝突。
String end = "\r\n";end作為行末的結束,必須由\r\n組成,不可更改。
String twoHyphens = "--";作為分隔符,由兩個-組成,不可更改。

每部分訊息體都是以下格式

--boundary+end
內容描述資訊+end
end 這個空行必須有
內容

最後所有資訊都寫完之後訊息主題是以 --boundary-- 作為結束。
其中描述資訊Content-Disposition: form-data;值一定得為form-data

如果是檔案的話需要有name 和filename 而位元組流或文字就只有一個name 對於多個檔案,只需要將其name設為不同 即可在伺服器端獲取到。在php編寫的伺服器端中,若為檔案,則可以在$_FILES['name']中取到,而那些文字資訊是存在$_POST['title']中的,注意下不同之處(其中name和title為你移動端傳過去的值)

這裡以一個富文字編輯器內容(轉換成html格式string)傳輸到伺服器上為例,將圖片單獨取出並編號,以檔案的方式上傳,其餘資訊引數以文字格式上傳,之後再伺服器端儲存這些圖片,並將html中圖片地址替換成伺服器地址並生成html檔案。

Andorid端程式碼如下:

final String end = "\r\n";
        final String twoHyphens = "--";
        final String boundary = "[email protected]*_*@EmPty_xL--------";
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    URL url = new URL(url_upload_content);
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    //設定請求方式
                    httpURLConnection.setRequestMethod("POST");
                    // 設定每次傳輸的流大小,可以有效防止手機因為記憶體不足崩潰
                    // 此方法用於在預先不知道內容長度時啟用沒有進行內部緩衝的 HTTP 請求正文的流。
                    httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K
                    // 設定是否向httpUrlConnection輸出,因為這個是post請求,引數要放在
                    // http正文內,因此需要設為true, 預設情況下是false;
                    httpURLConnection.setDoOutput(true);
                    // 設定是否從httpUrlConnection讀入,預設情況下是true;
                    httpURLConnection.setDoInput(true);
                    // Post 請求不能使用快取
                    httpURLConnection.setUseCaches(false);
                    // 設定請求的超時時間
                    httpURLConnection.setReadTimeout(5000);
                    httpURLConnection.setConnectTimeout(5000);
                    /* 設定請求屬性 */
                    httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
                    httpURLConnection.setRequestProperty("Charset", "UTF-8");
                    httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

                    //POST請求
                    DataOutputStream out = new DataOutputStream(httpURLConnection.getOutputStream());
                    //寫頭部
                    //如果檔案中還有圖片沒有處理
                    int image_number=1;
                    int start=0;
                    StringBuffer contents=new StringBuffer(content);
                    //寫入標題
                    out.writeBytes(twoHyphens+boundary + end);
                    out.writeBytes("Content-Disposition: form-data; "+
                            "name=\"title\"" + end);
                    out.writeBytes(end);
                    out.writeBytes(title_name+end);
                    while (contents.indexOf("<img src=",start)>=0){
                        int k=contents.indexOf("<img src=",start);
                        int url_end=contents.indexOf(" ", k+5) - 1;
                        String image_uri=contents.substring(k + 10,url_end);
                        File file=new File(image_uri);
                        Log.v("TAG",String.valueOf(file.length()));
                        String fileName=map.get("user_account") + String.valueOf(image_number)+".png";

                        out.writeBytes(twoHyphens+boundary + end);
                        out.writeBytes("Content-Disposition: form-data; "+
                                "name=\""+"contentimage"+String.valueOf(image_number)+"\";filename=\"" +
                                fileName + "\"" + end);
                        out.writeBytes(end);
                        //寫入圖片內容
                        FileInputStream fStream = new FileInputStream(file);
                         /* 設定每次寫入8192bytes */
                        int bufferSize = 8192;
                        byte[] buffer = new byte[bufferSize];   //8k
                        int length = 0;
                         /* 從檔案讀取資料至緩衝區 */
                        while ((length = fStream.read(buffer)) != -1) {
                         /* 將資料寫入DataOutputStream中 */
                            out.write(buffer, 0, length);
                        }
                        fStream.close();
                        out.writeBytes(end);
                        int u=contents.indexOf(image_uri);
                        contents.replace(k+10,url_end,fileName);
                        start=contents.indexOf(" ",k+5);
                        image_number++;
                    }
                    //寫入html字串s
                    out.writeBytes(twoHyphens+boundary + end);
                    out.writeBytes("Content-Disposition: form-data; "+
                            "name=\"text\"" + end);
                    out.writeBytes(end);
                    out.writeBytes(contents+end);
                    //寫入賬號名
                    out.writeBytes(twoHyphens+boundary + end);
                    out.writeBytes("Content-Disposition: form-data; "+
                            "name=\"user_account\"" + end);
                    out.writeBytes(end);
                    out.writeBytes(map.get("user_account")+end);
                    //寫入圖片個數
                    out.writeBytes(twoHyphens+boundary + end);
                    out.writeBytes("Content-Disposition: form-data; "+
                            "name=\"imagenumber\"" + end);
                    out.writeBytes(end);
                    out.writeBytes(String.valueOf(image_number-1)+end);
                    //訊息主體最後一行
                    out.writeBytes(twoHyphens + boundary + twoHyphens + end);
                     /* 關閉流,寫入的東西自動生成Http正文*/
                         /* 關閉DataOutputStream */
                    out.close();

                    //讀取響應流
                    //讀取響應
                    BufferedReader reader = new BufferedReader(new InputStreamReader(
                            httpURLConnection.getInputStream()));
                    String lines;
                    StringBuffer sb = new StringBuffer();
                    while ((lines = reader.readLine()) != null) {
                        lines = new String(lines.getBytes(), "utf-8");
                        sb.append(lines);
                    }
                    Log.v("TAG", sb.toString());
                    reader.close();
                    httpURLConnection.disconnect();

                    /*JSONObject response = new JSONObject(sb.toString());
                    Message msg = Message.obtain();
                    msg.obj = response;
                    msg.what = UPLOAD_CONTENT;
                    // 傳送這個訊息到訊息佇列中
                    handler.sendMessage(msg);*/

                }catch (Exception e){
                    Log.getStackTraceString(e);
                }
            }
        }).start();

php端如下:

<?php
    $response =array();
    $url="http://172.16.1.93:80/ActivitySharing/";
    //判斷是否有所需要的資訊:
    if (isset($_POST['user_account']) && isset($_FILES['contentimage1']) && isset($_POST['text'])
        && isset($_POST['imagenumber'])  && isset($_POST['title']) )
    {
        $user_account=$_POST['user_account'];
        $title=$_POST['title'];
        $imagenumber=(integer)$_POST['imagenumber'];
        $path="./"."contents/".$user_account."_".(String)time().rand(0,1000)."/";
        if (!is_dir($path)) mkdir(iconv("UTF-8", "GBK", $path));
        $flag=true;
        for($i=1;$i<=$imagenumber;$i++)
            if (!move_uploaded_file($_FILES['contentimage'.$i]['tmp_name'], $path."contentimage".(String)$i.".png"))
            {
                $flag=false;
                break;
            }
        //判斷圖片是否全部儲存完畢
        if (($i>$imagenumber) && ($flag)){
            $text=$_POST['text'];
            for($i=1;$i<=$imagenumber;$i++){
                if (isset($_FILES['contentimage'.$i]['name']))
                $text=str_replace($_FILES['contentimage'.$i]['name'],$url.substr($path,1)."contentimage".(String)$i,$text);
            }
            $myfile = fopen($path."index.html", "w");
            fwrite($myfile, $text);
            fclose($myfile);

            //返回解析完成訊息
            $response["result"]="SUCCESSFUL";
            $response["message"]="upload files successful";
            echo json_encode($response);
            return;
        }
        else{
            $response["result"]="FAILED";
            $response["message"]="upload images failed";
            echo json_encode($response);
            return;
        }
    }
    else{
        $response["result"]="FAILED";
        $response["message"]="upload failed";
        echo json_encode($response);
    }

?>

相關推薦

AndroidAndroid伺服器互動 POST圖片檔案文字內容 GET下載圖片

這裡伺服器端採用的是php解析內容 HTTP請求   HTTP 請求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 這幾種。用於資料互動的最基本方法一般為GET、POST、PUT、DELETE。對

Android使用https伺服器互動的正確姿勢

HTTPS 使用 SSL 在客戶端和伺服器之間進行加密通訊,錯誤地使用 SSL ,將會導致其它人能夠攔截網路上的應用資料。 使用一個包含公鑰及與其匹配的私鑰的證書配置伺服器,作為 SSL 客戶端與伺服器握手的一部分,伺服器將通過使用公鑰加密簽署其證書來證明自己具有私鑰。 主機平臺一般包含其信任的知名 CA

Android 客戶端伺服器互動方式

突然想到一個問題就是Android客戶端與伺服器互動有幾種方式,因為在腦袋裡想當然的就是webservices和json。要在Android手機客戶端與pc伺服器互動,需要滿足下面幾種條件:跨平臺、傳輸資料格式標準、互動方便...。 為了與伺服器通訊其實無非就兩種協議HTT

php面向過程的文件過程

pre maxsize html 維數 exists 錯誤號 blog spa htm 1 //執行完整的文件上傳 2 $path = "./uploads"; //文件上傳的指定目錄 3 $upfile = $_FILES[‘pic‘]; //

使用git將項目到github(最簡單方法)

名稱 posit gitignore nor this strong 共享 window mas 原文地址:http://www.cnblogs.com/cxk1995/p/5800196.html 首先你需要一個github賬號,所有還沒有的話先去註冊吧! https:/

mysql中為同一張表取別名

select employee1.name as employee from employee employee1,employee employee2 where employee1.managerId=employee2.id and

LinuxCentOS Linux 7.4系統檔案失敗:sftp put: failed to upload d:/0data/test.txt Failure

CentOS Linux 7.4系統上傳檔案失敗 場景: 使用SecureCRT軟體下sftp長傳一個幾十M的檔案上傳失敗,報錯如下:sftp put: failed to upload d:/0data/test.txt Failure 解決: 一開始以為是CRT軟體的問題,但使用Xs

JS封裝相容正版IE9的控制元件,支援圖片格式,圖片大小,圖片寬高驗證,支援非圖片樣式

先廢話一小段,大家好,本人首篇處女作,為什麼要實現一個上傳控制元件呢,必然是公司需要嘛,實現整個過程挺揪心的,因為要解決ie9這個相容性問題,整體來說我前後用了五天的時間來實現。依賴了jquery,其實也可以使用原生編寫,不過想偷偷懶,公司也推薦使用jquery。因為是第一次

微信小程式開發筆記檔案超過10

【小程式筆記】wx.uploadFile(OBJECT) 先說說遇到的問題: 小程式可通過wx.uploadFile(OBJECT)介面上傳手機檔案至伺服器,但是在文件中關於請求中有這麼一段說明: request、uploadFile、down

SVNWindows下如何使用SVN新增刪除檔案

操作步驟 1. 本地建立倉庫:在本地新建資料夾,右鍵 —> TortoiseSVN —> Create repository here; 2. 下載已有倉庫:在本地新建資料夾,右鍵 —> Checkout —> 輸入使用者名稱密碼、下載的檔案路徑;

中間有跳板機,mac電腦如何伺服器之間進行下載檔案

安裝zssh brew install zssh 上傳檔案 zssh登陸上跳板機 在跳板機上ssh到相應伺服器 在伺服器上cd至相應要放上傳檔案的目錄 rz -bye //在遠端伺服器的相應目錄上執行此命令,表示做好接

spring cloud實戰思考(二) 微服務之間通過fiegn文件1

jar 多文件 上傳文件 ret nmap spa 不同 port 問題 需求場景: 微服務之間調用接口一次性上傳多個文件。 上傳文件的同時附帶其他參數。 多個文件能有效的區分開,以便進行不同處理。   Spring cloud的微服務之間接口調用使用Feign。原裝的

Linux環境下庫svn安裝配置(獨立庫,配置檔案

[先在伺服器中開啟放行 3690 埠!!!] (1)檢視是否已經安裝了svn 命令:svnserve --version 沒有安裝,出現下面資訊-> 已經安裝,出現下面版本資訊-> 檢視安裝svn的路徑資訊:rpm -ql subversion

flask 伺服器上面下載檔案 ,客戶端一次性檔案

  #encoding=utf8 import flask,os,sys,time from flask import request,send_from_directory import multiEmbeddings  import tensorflow as tf &n

Struts檔案下載詳解 _檔案

     在上一篇中給大家列出的單個檔案的上傳,那麼這一篇咱們講講上傳多個檔案改怎麼作呢?由於過程和上傳單個檔案的類似,所以在這裡不細說,相信大家都能看懂,看不懂的可以在評論區留言,我看到之後會及時

C# HTTP系列13 以form-data方式檔案以及鍵值對集合到遠端伺服器

系列目錄     【已更新最新開發文章,點選檢視詳細】 類似於以下場景,將表單中的使用者資訊(包含附件)上傳到伺服器並儲存到資料庫中, <form id="form1" runat="server" action="UserManageHandler.as

AndroidAppApp之間的互動

今天剛好公司有一個Android無介面外掛化的列印App需求,隨便在這裡寫下一點心得 知識點分析: 無介面 可比本公司的其他App任意呼叫 隱藏App的啟動圖示 一. 外掛App: (一)修改ac

Unity3dUnity5Android互動通訊(使用Android Studio2.4)

摘自CSDN作者,網址:http://blog.csdn.net/u010377179/article/details/53105062#comments(如有侵權,聯絡刪除。謝謝!) 現在網上的Unity與Android通訊的教程,要麼是Unity版本不是較新的,要麼

android伺服器互動總結(json,post,xUtils,Volley,Gson)

(最後一次更新2016 - 12 - 21) 更新內容:由於android 6.0完全拋棄了HttpClinet,所以,原生的網路請求,建議使用HttpURLConnection,本文的第三方框架,都是去年比較老的,現在xutils都更新到xutils3了,沒有大檔案的網

android客戶端伺服器互動 如何保持session

最近在開發專案的過程中,遇到android與web伺服器要在同一session下通訊的問題。 在解決問題前先回顧下Session與Cookie: Cookie和Session都為了用來儲存狀態資訊,都是儲存客戶端狀態的機制,它們都是為了解決HTTP無狀態的問題而所做