【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);
}
?>
相關推薦
【Android】Android與伺服器互動 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
【Linux】CentOS 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
【SVN】Windows下如何使用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
【Android】App與App之間的互動
今天剛好公司有一個Android無介面外掛化的列印App需求,隨便在這裡寫下一點心得 知識點分析: 無介面 可比本公司的其他App任意呼叫 隱藏App的啟動圖示 一. 外掛App: (一)修改ac
【Unity3d】Unity5與Android互動通訊(使用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無狀態的問題而所做