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:
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="someXml.xml"
Content-Type: text/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
)
you can go this way for uploading to server
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
InputStreamEntity reqEntity = new InputStreamEntity(new FileInputStream(filePath), -1);
reqEntity.setContentType("binary/octet-stream");
reqEntity.setChunked(true); // Send in multiple parts if needed
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
I have done something similar to access webservices. The soap request was an XML request. See the code below:
package abc.def.ghi;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;
public class WebServiceRequestHandler {
public static final int CONNECTION_TIMEOUT=10000;
public static final int SOCKET_TIMEOUT=15000;
public String callPostWebService(String url, String soapAction, String envelope) throws Exception {
final DefaultHttpClient httpClient=new DefaultHttpClient();
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, SOCKET_TIMEOUT);
HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);
// POST
HttpPost httppost = new HttpPost(url);
// add headers. set content type as XML
httppost.setHeader("soapaction", soapAction);
httppost.setHeader("Content-Type", "text/xml; charset=utf-8");
String responseString=null;
try {
// the entity holds the request
HttpEntity entity = new StringEntity(envelope);
httppost.setEntity(entity);
ResponseHandler<String> rh=new ResponseHandler<String>() {
// invoked on response
public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
HttpEntity entity = response.getEntity();
StringBuffer out = new StringBuffer();
// read the response as byte array
byte[] b = EntityUtils.toByteArray(entity);
// write the response byte array to a string buffer
out.append(new String(b, 0, b.length));
return out.toString();
}
};
responseString=httpClient.execute(httppost, rh);
}
catch (UnsupportedEncodingException uee) {
throw new Exception(uee);
}catch (ClientProtocolException cpe){
throw new Exception(cpe);
}catch (IOException ioe){
throw new Exception(ioe);
}finally{
// close the connection
httpClient.getConnectionManager().shutdown();
}
return responseString;
}
}
Using your code, the following should work:
response.setContentType("Your MIME type");
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).