Неверная длина контента отправляется на сервер?

StackOverflow https://stackoverflow.com/questions/4706087

Вопрос

Я пытаюсь загрузить фотографию в популярную службу 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top