2010-05-29 100 views
116

我想使用Http Post從Android客戶端向Django服務器發送圖像。該圖像是從畫廊中選擇的。目前,我使用列表值名稱對將必要的數據發送到服務器並從JSON接收來自Django的響應。對於圖像可以使用相同的方法(使用嵌入在JSON響應中的圖像的URL)?使用Http Post發送圖像

此外,這是一個更好的方法:遠程訪問圖像,而無需從服務器下載或下載並將它們存儲在位圖數組中並在本地使用它們?圖像數量很少(< 10),尺寸較小(50 * 50傾角)。

任何教程來解決這些問題將不勝感激。

編輯:從畫廊中選擇的圖像將其縮放到所需尺寸後發送到服務器。

回答

140

我打算假設您知道要上傳的圖像的路徑和文件名。將此字符串添加到您的NameValuePair,使用image作爲鍵名。

發送圖像可以使用HttpComponents libraries完成。下載帶有依賴包的最新HttpClient(當前爲4.0.1)二進制文件,並將apache-mime4j-0.6.jarhttpmime-4.0.1.jar複製到您的項目並將它們添加到您的Java構建路徑。

您將需要將以下導入添加到您的班級。

import org.apache.http.entity.mime.HttpMultipartMode; 
import org.apache.http.entity.mime.MultipartEntity; 
import org.apache.http.entity.mime.content.FileBody; 
import org.apache.http.entity.mime.content.StringBody; 

現在您可以創建一個MultipartEntity將圖像附加到您的POST請求。以下代碼顯示瞭如何執行此操作的示例:

public void post(String url, List<NameValuePair> nameValuePairs) { 
    HttpClient httpClient = new DefaultHttpClient(); 
    HttpContext localContext = new BasicHttpContext(); 
    HttpPost httpPost = new HttpPost(url); 

    try { 
     MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); 

     for(int index=0; index < nameValuePairs.size(); index++) { 
      if(nameValuePairs.get(index).getName().equalsIgnoreCase("image")) { 
       // If the key equals to "image", we use FileBody to transfer the data 
       entity.addPart(nameValuePairs.get(index).getName(), new FileBody(new File (nameValuePairs.get(index).getValue()))); 
      } else { 
       // Normal string data 
       entity.addPart(nameValuePairs.get(index).getName(), new StringBody(nameValuePairs.get(index).getValue())); 
      } 
     } 

     httpPost.setEntity(entity); 

     HttpResponse response = httpClient.execute(httpPost, localContext); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

我希望這可以幫助您在正確的方向上找到一點點。

+0

正如我前面提到的,我發送的圖像尺寸很小。那麼我需要使用MultiPartEntity來發送它們嗎? – primpap 2010-05-30 01:03:05

+6

我肯定會推薦這個。這樣你可能可以使用Django的功能來接收圖像並將其存儲起來。另一種方法是將圖像中的字節流編碼爲base64編碼的字符串,並將其解碼爲服務器端。但在我看來,這太麻煩了,而不是要走的路。 – Piro 2010-05-30 01:16:57

+0

從圖庫中選擇的圖像在縮放到50 * 50傾角後發送到服務器。所以我沒有添加到列表值名稱對的路徑。所以只有你提到的第二種方法似乎是可能的。 – primpap 2010-05-30 07:11:26

-12

我通常這樣做在線程處理JSON響應:

try { 
    Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent()); 
} catch (MalformedURLException e) { 
    e.printStackTrace(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

如果您需要做的圖像轉換,你需要創建一個可繪製的,而不是一個位圖。

+3

問題是如何發佈圖片,而不是如何得到它。 – dwbrito 2014-03-04 11:51:03

13

版本4.3.5更新的代碼

  • 的HttpClient-4.3.5.jar
  • 的HttpCore-4.3.2.jar
  • httpmime-4.3.5.jar

由於MultipartEntity已被棄用。請參閱下面的代碼。

String responseBody = "failure"; 
HttpClient client = new DefaultHttpClient(); 
client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); 

String url = WWPApi.URL_USERS; 
Map<String, String> map = new HashMap<String, String>(); 
map.put("user_id", String.valueOf(userId)); 
map.put("action", "update"); 
url = addQueryParams(map, url); 

HttpPost post = new HttpPost(url); 
post.addHeader("Accept", "application/json"); 

MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
builder.setCharset(MIME.UTF8_CHARSET); 

if (career != null) 
    builder.addTextBody("career", career, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (gender != null) 
    builder.addTextBody("gender", gender, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (username != null) 
    builder.addTextBody("username", username, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (email != null) 
    builder.addTextBody("email", email, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (password != null) 
    builder.addTextBody("password", password, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (country != null) 
    builder.addTextBody("country", country, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (file != null) 
    builder.addBinaryBody("Filedata", file, ContentType.MULTIPART_FORM_DATA, file.getName()); 

post.setEntity(builder.build()); 

try { 
    responseBody = EntityUtils.toString(client.execute(post).getEntity(), "UTF-8"); 
// System.out.println("Response from Server ==> " + responseBody); 

    JSONObject object = new JSONObject(responseBody); 
    Boolean success = object.optBoolean("success"); 
    String message = object.optString("error"); 

    if (!success) { 
     responseBody = message; 
    } else { 
     responseBody = "success"; 
    } 

} catch (Exception e) { 
    e.printStackTrace(); 
} finally { 
    client.getConnectionManager().shutdown(); 
} 
+0

需要哪個jar包? – 2014-09-11 04:55:29

+3

httpclient-4.3.5.jar httpcore-4.3.2.jar httpmime-4.3.5.jar – 2014-09-11 06:05:24

+0

addQueryParams返回什麼? – San 2015-10-21 06:40:28

9

循環J庫可用於直接的用於此目的:

SyncHttpClient client = new SyncHttpClient(); 
RequestParams params = new RequestParams(); 
params.put("text", "some string"); 
params.put("image", new File(imagePath)); 

client.post("http://example.com", params, new TextHttpResponseHandler() { 
    @Override 
    public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { 
    // error handling 
    } 

    @Override 
    public void onSuccess(int statusCode, Header[] headers, String responseString) { 
    // success 
    } 
}); 

http://loopj.com/

+0

謝謝!!!節省了我的時間.... – 2016-06-25 17:56:00

5

我掙扎了很多努力來實現發佈來自Android客戶端一個圖像使用與Servlet httpclient-4.3.5.jar,httpcore-4.3.2.jar,httpmime-4.3.5.jar。我總是遇到運行時錯誤。我發現基本上你不能在Android上使用這些jar,因爲Google在Android中使用的是舊版本的HttpClient。這裏的解釋是http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html。您需要從android http-client library獲取httpclientandroidlib-1.2.1 jar。然後將您的導入從or.apache.http.client更改爲ch.boye.httpclientandroidlib。希望這可以幫助。