我想使用Http Post将图像从android客户端发送到Django服务器。该图像是从图库中选择的。目前,我正在使用列表值名称对来将必要的数据发送到服务器,并从JSON中接收来自Django的响应。可以对图像使用相同的方法(对于JSON响应中嵌入的图像使用URL)吗?

另外,这是一种更好的方法:远程访问图像而不从服务器下载图像或将其下载并存储在Bitmap数组中并在本地使用吗?图像数量很少(<10个),尺寸很小(50 * 50浸)。

解决这些问题的任何教程都将不胜感激。

编辑:从图库中选择的图像在将其缩放到所需大小后会发送到服务器。

#1 楼

我将假设您知道要上传的图像的路径和文件名。使用NameValuePair作为键名将此字符串添加到image

可以使用HttpComponents库发送图像。下载具有相关性软件包的最新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();
    }
}


我希望这对您在正确的方向有所帮助。

评论


我绝对会推荐这个。这样,您可能可以使用Django功能接收图像并轻松存储它。另一种方法是将图像中的字节流编码为base64编码的字符串,然后在服务器端对其进行解码。但是,在我看来,这太麻烦了,而不是要走的路。

– Piro
2010年5月30日在1:16



大家好,没有MultipartEntity,有没有办法做到这一点?我真的不想只为这4个类导入所有的Apache HC。 :-(

–尼尔·特拉夫(Neil Traft)
2010年8月1日在15:53

只需使用所需的Mime类型向FileBody添加第二个参数即可。例如:new FileBody(新文件(nameValuePairs.get(index).getValue()),“ image / jpeg”)

– Piro
2011年3月8日22:25



似乎不赞成使用多实体吗?

–内南
2014年1月5日上午10:18

@Piro我也在考虑编辑您的答案。多部分实体以及您使用的字符串体版本会被贬值。我不编辑的原因是因为我无法像您一样将所有数据绑定到namevaluepairs中。

–非法论点
2014-2-25在7:42

#2 楼


版本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();
}


评论


需要哪些罐子包装?

–user679937
2014年9月11日下午4:55

httpclient-4.3.5.jar httpcore-4.3.2.jar httpmime-4.3.5.jar

– AZ_
2014年9月11日下午6:05

addQueryParams返回什么?

–圣
2015年10月21日在6:40

#3 楼

为此,可以直接使用loopj库:

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/

#4 楼

我在尝试使用httpclient-4.3.5.jar,httpcore-4.3.2.jar,httpmime-4.3.5.jar将图像从Android客户端发布到servlet时费了很多力气。我总是遇到运行时错误。我发现基本上您不能在Android上使用这些jar,因为Google在Android中使用的是较旧版本的HttpClient。此处的解释是http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html。您需要从android http-client库获取httpclientandroidlib-1.2.1 jar。然后将您的导入从or.apache.http.client更改为ch.boye.httpclientandroidlib。希望这会有所帮助。

#5 楼

我通常在处理json响应的线程中执行此操作:

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


如果需要对图像进行转换,则需要创建Drawable而不是位图。

评论


问题是如何发布图像,而不是如何获取图像。

– dwbrito
2014年4月4日在11:51