2010-05-29 99 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。希望这可以帮助。