Отправка изображений с помощью Http Post
Я хочу отправить изображение из клиента android на сервер Django с помощью Http Post. Изображение выбрано из галереи. В настоящее время я использую имя имени списка Pairs для отправки необходимых данных на сервер и получения ответов от Django в JSON. Можно ли использовать один и тот же подход для изображений (с URL-адресами для изображений, встроенных в ответы JSON)?
Кроме того, это лучший способ: удаленно удалять изображения, не загружая их с сервера, не загружая и не сохраняя их в массиве Bitmap и не используя их локально? Изображения немногочисленны (< 10) и небольшие по размеру (50 * 50 dip).
Любое учебное пособие для решения этих проблем будет высоко оценено.
Изменить: изображения, выбранные из галереи, отправляются на сервер после масштабирования до требуемого размера.
Ответы
Ответ 1
Я предполагаю, что вы знаете путь и имя файла, который вы хотите загрузить. Добавьте эту строку в свой NameValuePair
, используя image
в качестве имени ключа.
Отправка изображений может быть выполнена с помощью библиотеки HttpComponents. Загрузите последний HttpClient (в настоящее время 4.0.1) двоичный с пакетом зависимостей и копией apache-mime4j-0.6.jar
и httpmime-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();
}
}
Надеюсь, это поможет вам немного в правильном направлении.
Ответ 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();
}
Ответ 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
Я изо всех сил пытался внедрить отправку изображения с Android-клиента на сервлет с помощью httpclient-4.3.5.jar, httpcore-4.3.2.jar, httpmime-4.3.5.jar. У меня всегда была ошибка времени выполнения. Я узнал, что в основном вы не можете использовать эти банки с Android, поскольку Google использует устаревшую версию HttpClient в Android. Объяснение здесь http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html. Вам нужно получить банку httpclientandroidlib-1.2.1 из андроидной http-клиентской библиотеки. Затем измените импорт с 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 вместо Bitmap.