Ошибка «Неправильно отформатированный запрос» после переключения с Commons HttpClient на HttpComponents

У меня есть код, отправляющий multipart/form-data запрос в API. Использование Apache commons-httpclient 3.1 работает, однако при переходе на httpclient 4.3.5 возникают проблемы с API. Ниже вы можете найти оба примера кода. Поскольку это связано с API Salesforce, я также отправил вопрос на SFSE, так как я до сих пор не уверен, проблема на моей стороне или на их стороне. Однако у меня вопрос: правильно ли я перенес код на 4.3.5? Если да, изменилось ли что-нибудь в поведении httpclient, связанном с выполнением запросов multipart/form-data?

Ниже приведены примеры кода:

commons-httpclient 3.1

String json = "{ \"body\":{ \"messageSegments\":[ { \"type\":\"Text\", \"text\":\"Here is another receipt.\" } ] }, \"capabilities\":{ \"content\":{ \"title\":\"receipt2\"} } }";

PostMethod filePost = new PostMethod("https://eu3.salesforce.com/services/data/v32.0/chatter/feed-elements/<some_feed_element_id>/capabilities/comments/items");
filePost.addRequestHeader("Authorization", token());

StringPart jsonPart = new StringPart("json", json);
jsonPart.setContentType(ContentType.APPLICATION_JSON.getMimeType());

FilePart filePart = new FilePart("feedElementFileUpload", file);
filePart.setContentType(ContentType.APPLICATION_OCTET_STREAM.getMimeType());

Part[] parts = { jsonPart, filePart };
filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
int response = httpclient.executeMethod(filePost);

Журналы проводки/контекста: http://pastebin.com/RCg20Ygn

httpclient 4.3.5

String json = "{ \"body\":{ \"messageSegments\":[ { \"type\":\"Text\", \"text\":\"Here is another receipt.\" } ] }, \"capabilities\":{ \"content\":{ \"title\":\"receipt2\"} } }";

String attachmentName = "package.xml";
CloseableHttpClient client = HttpClientBuilder
    .create()
    .setDefaultHeaders(Lists.newArrayList())
    .build();
HttpPost post = new HttpPost(
   "https://eu3.salesforce.com/services/data/v32.0/chatter/feed-elements/<feed_element_id>/capabilities/comments/items"
);
post.addHeader(HttpHeaders.AUTHORIZATION, token());
post.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.MULTIPART_FORM_DATA.getMimeType());

post.setEntity(
    MultipartEntityBuilder.create()
        .setStrictMode()
        .addPart(
            "json",
            new StringBody(
                json,
                ContentType.APPLICATION_JSON
            )
        )
        .addPart(
            "feedElementFileUpload",
            new FileBody(
                new File(attachmentName),
                ContentType.APPLICATION_OCTET_STREAM,
                attachmentName
            )
        )
        .build()
);
CloseableHttpResponse response = client.execute(post);

Журналы проводки/контекста: http://pastebin.com/EHXd1y50

ОБНОВЛЕНИЕ 1:

Я пробовал все три доступных режима для MultipartEntityBuilder (STRICT, BROWSER_COMPATIBLE, RFC6532), но все равно не работает.


person Haris Osmanagić    schedule 03.12.2014    source источник


Ответы (1)


Попробуйте использовать «совместимый с браузером» режим вместо «строгого» при построении объекта запроса с помощью MultipartEntityBuilder.

ОБНОВЛЕНИЕ 1:

"Content-Type: multipart/form-data[\r][\n]"

Это явно неправильно (отсутствует граничный атрибут) и, вероятно, является причиной отклонения запроса.

Удалите эту строку и повторите попытку.

post.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.MULTIPART_FORM_DATA.getMimeType());
person ok2c    schedule 04.12.2014
comment
Спасибо за ваш ответ! Я только что попробовал его со всеми тремя доступными режимами, и он все еще не работает. - person Haris Osmanagić; 04.12.2014
comment
Публикуйте проводные/контекстные журналы сеансов HC3 и HC4. Дополнительные сведения см. в руководстве по ведению журнала HttpClient. - person ok2c; 04.12.2014
comment
Я добавил журналы ниже соответствующих примеров кода. - person Haris Osmanagić; 05.12.2014
comment
Работает! Миллион раз спасибо! - person Haris Osmanagić; 05.12.2014