Неверная длина контента отправляется на сервер?
-
11-10-2019 - |
Вопрос
Я пытаюсь загрузить фотографию в популярную службу DailyBooth через их новый API через метод задокументировано здесь.
Проблема в том, что сервер отвечает:
<html><head><title>411 Length Required</title>...
Код, который я использую для отправки этих данных, здесь:
// 2: Build request
HttpClient httpclient = new DefaultHttpClient();
SharedPreferences settings = DailyboothShared.getPrefs(DailyboothTakePhoto.this);
String oauth_token = settings.getString("oauth_token", "");
HttpPost httppost = new HttpPost(
"https://api.dailybooth.com/v1/pictures.json?oauth_token=" + oauth_token);
Log.d("upload", "Facebook: " + facebook);
Log.d("upload", "Twitter: " + twitter);
try {
InputStream f = getContentResolver().openInputStream(snap_url);
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
entity.addPart("picture", new InputStreamBody(f, snap_url.getLastPathSegment()));
entity.addPart("blurb", new StringBody(blurb));
entity.addPart("publish_to[facebook]", new StringBody(facebook));
entity.addPart("publish_to[twiter]", new StringBody(twitter));
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
Log.d("upload", response.toString());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
// do something?
} else {
Log.d("upload", "Something went wrong :/");
}
Log.d("upload", EntityUtils.toString(response.getEntity()));
} catch (Exception ex) {
ex.printStackTrace();
}
Я понятия не имею, что делаю не так.
Решение
Вы используете либо StringBody
а также InputStreamBody
Классы, которые описывают содержание вашей многопотечной. Глядя на источники, StringBody.getContentLength()
возвращает длину строки, но InputStreamBody
Всегда возвращай -1
, и я думаю, что это сделано для случая, вам нужно загрузить некоторые данные на сервер, не зная его размера, и начать загрузку, пока данные приходят по потоку.
Если вы хотите иметь возможность установить длину контента, вам нужно заранее знать размер вашего потока, что вы можете сделать, если это так, чтобы установить InputStreamBody
туда:
new InputStreamBody(f, snap_url.getLastPathSegment()) {
public long getContentLength() {
return /*your length*/;
}
}
или сбросить свой поток в byte[]
массив и проход ByteArrayInputStream
в InputStreamBody
, конечно, вы потеряете потоковую способность, поскольку вам нужно кэшировать свои данные в памяти, прежде чем отправлять их ...
Как вы сказали, что работаете над изображениями, это изображения File
случайно? Если да, у вас тоже есть FileBody
которые возвращают правильный content-length
.