views:

538

answers:

3

EDIT :

I am trying to send an xml file as a post request in Android.

The server accepts text/xml. I tried creating a MultipartEntity, which has a content type of multipart/form-data.

 HttpClient httpClient = new DefaultHttpClient();

    /* New Post Request */
    HttpPost postRequest = new HttpPost(url);

    byte[] data = IOUtils.toByteArray(payload);

    /* Body of the Request */
     InputStreamBody isb = new InputStreamBody(new ByteArrayInputStream(data), "uploadedFile");
    MultipartEntity multipartContent = new MultipartEntity();
    multipartContent.addPart("uploadedFile", isb);

    /* Set the Body of the Request */
    postRequest.setEntity(multipartContent);

    /* Set Authorization Header */
    postRequest.setHeader("Authorization", authHeader);
    HttpResponse response = httpClient.execute(postRequest);
    InputStream content = response.getEntity().getContent();
    return content;

However I get an error saying the content type cannot be consumed.

The server refused this request because the request entity is in a format not supported by the requested resource for the requested method (Cannot consume content type).

How do I change the content type of the request?

Edit:

A: 

Using your code, the following should work:

response.setContentType("Your MIME type");
Chris J
I need to change the content type of the request.
kunjaan
A: 

Regardless of API, content type is negotiated via a header with the 'Content-Type' key:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

You cannot control what the service expects. It's a part of their contract. You're probably sending 'text/plain' and they're expecting something in the realm of 'multipart/form-data' (think html form data).

Droo
I think http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html is more applicable in this case, multipart requests can specify more than one Content-Type. I would also think that HttpClient detects and sets the correct one for the attached file.
Lauri Lehtinen
But here...I'll google it for you: http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/methods/PostMethod.html call setParameter("Content-Type", "theexpected/type")
Droo
Whoever voted this response down is a retard.
Droo
+2  A: 

Long story short - use another constructor for your InputStreamBody that lets you specify the mime type you wish to use. If you don't, the parts in your multipart request will not have a Content-Type specified (see below for details). Consequently, the server does not know what type the file is, and in your case might be refusing to accept it (mine accepted them anyway, but I assume this is driven by config). If this still doesn't work, you might have a server-side issue.

Note: Changing the Content-Type of the request itself to anything but multipart/form-data; boundary=someBoundary renders the request invalid; the server will not correctly parse the multipart parts.

Long story long - here's my findings.

Given the following code:

byte[] data = "<someXml />".getBytes();
multipartContent.addPart("uploadedFile", new InputStreamBody(new ByteArrayInputStream(data), "text/xml", "somefile.xml"));
multipartContent.addPart("otherPart", new StringBody("bar", "text/plain", Charset.forName("UTF-8")));
multipartContent.addPart("foo", new FileBody(new File("c:\\foo.txt"), "text/plain"));

The HttpClient posts the following payload (captured w/ Wireshark):

POST /upload.php HTTP/1.1
Transfer-Encoding: chunked
Content-Type: multipart/form-data; boundary=SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3
Host: thehost.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1-alpha2 (java 1.5)

--SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3
Content-Disposition: form-data; name="uploadedFile"; filename="text/xml"
Content-Type: someXml.xml
Content-Transfer-Encoding: binary

<someXml />
--SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3
Content-Disposition: form-data; name="otherPart"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

yo
--SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3
Content-Disposition: form-data; name="foo"; filename="foo.txt"
Content-Type: text/plain
Content-Transfer-Encoding: binary

Contents of foo.txt

--SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3--

On the server, the following PHP script:

<?php
print_r($_FILES);
print_r($_REQUEST);

spitted out the following:

Array
(
    [uploadedFile] => Array
        (
            [name] => someXml.xml
            [type] => text/xml
            [tmp_name] => /tmp/php_uploads/phphONLo3
            [error] => 0
            [size] => 11
        )

    [foo] => Array
        (
            [name] => foo.txt
            [type] => text/plain
            [tmp_name] => /tmp/php_uploads/php58DEpA
            [error] => 0
            [size] => 21
        )

)
Array
(
    [otherPart] => yo
)
Lauri Lehtinen
Nah. No luck. The server still rejects my input. Is there someway I can send XML content without the making it multipart?
kunjaan
XML being plain text, you can use a StringEntity instead of the MultipartEntity. Wanna try pointing your Android code to http://systemout.com/upload.php and check out what it outputs (that's the page I tested with)?
Lauri Lehtinen
Hi Lauri. Thank you so much for helping me out. Sometimes I wonder at the power of the internet. Anyway I can only upvote you and give you some points. But the String Entity worked like a charm. Thank you again. Wish I could do more to show my gratitude. : )
kunjaan
Happy to hear it worked out. I learned a few lessons myself, haven't used the new HttpClient too much yet. What better way to get started than this?
Lauri Lehtinen