Android supports a limited version of apache's http client(v4).
typically if I want to send binary data using content type= application/octet-stream via POST,
I do the following:
HttpClient client = getHttpClient();
HttpPost method=new HttpPost("http://192.168.0.1:8080/xxx");
System.err.println("send to server "+s);
if(compression){
byte[]compressed =compress(s);
RequestEntity entity = new ByteArrayRequestEntity(compressed);
method.setEntity(entity);
}
HttpResponse resp=client.execute(method);
however ByteArrayRequestEntity is not supported on android. what can I do?
I think you want ByteArrayEntity. ByteArrayRequestEntity is from 3.x
Related
I am using the HttpPut to communicate with server in Android, the response code I am getting is 500.After talking with the server guy he said prepare the string like below and send.
{"key":"value","key":"value"}
now I am completely confused that where should i add this string in my request.
Please help me out .
I recently had to figure out a way to get my android app to communicate with a WCF service and update a particular record. At first this was really giving me a hard time figuring it out, mainly due to me not knowing enough about HTTP protocols, but I was able to create a PUT by using the following:
URL url = new URL("http://(...your service...).svc/(...your table name...)(...ID of record trying to update...)");
//--This code works for updating a record from the feed--
HttpPut httpPut = new HttpPut(url.toString());
JSONStringer json = new JSONStringer()
.object()
.key("your tables column name...").value("...updated value...")
.endObject();
StringEntity entity = new StringEntity(json.toString());
entity.setContentType("application/json;charset=UTF-8");//text/plain;charset=UTF-8
entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json;charset=UTF-8"));
httpPut.setEntity(entity);
// Send request to WCF service
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(httpPut);
HttpEntity entity1 = response.getEntity();
if(entity1 != null&&(response.getStatusLine().getStatusCode()==201||response.getStatusLine().getStatusCode()==200))
{
//--just so that you can view the response, this is optional--
int sc = response.getStatusLine().getStatusCode();
String sl = response.getStatusLine().getReasonPhrase();
}
else
{
int sc = response.getStatusLine().getStatusCode();
String sl = response.getStatusLine().getReasonPhrase();
}
With this being said there is an easier option by using a library that will generate the update methods for you to allow for you to update a record without having to manually write the code like I did above. The 2 libraries that seem to be common are odata4j and restlet. Although I haven't been able to find a clear easy tutorial for odata4j there is one for restlet that is really nice: http://weblogs.asp.net/uruit/archive/2011/09/13/accessing-odata-from-android-using-restlet.aspx?CommentPosted=true#commentmessage
Error 500 is Internal Server error. Not sure if this answers your question but I personally encountered it when trying to send a data URI for an animated gif in a PUT request formatted in JSON but the data URI was too long. You may be sending too much information at once.
I need to send a byte arrray file using WCF rest services. I have to send the data using HttpPost method in android. The code which i am using give the status as HTTP/1.1 400 Bad Request error.
private final static String URI = "http://192.168.1.15/QueryService/Import/Test";
final HttpPost request = new HttpPost(URI);
final HttpClient httpClient = new DefaultHttpClient();
final ByteArrayEntity entity = new ByteArrayEntity(fileToBytes(pathToOurFile));
entity.setContentType("application/octet-stream");
entity.setChunked(true);
request.setEntity(entity);
final HttpResponse hr = httpClient.execute(request);
final StatusLine status = hr.getStatusLine();
httpClient.getConnectionManager().shutdown();
It is difficult to tell what is wrong with your request. The standard way of resolving this kind of errors is:
Create a WCF client for your service. Verify that it works as expected.
Use Fiddler or another suitable tool to intercept the HTTP request your client is generating. Both the headers and the body are important.
Modify your Android request to generate the exact same request as the WCF client.
I was also facing same problem with WCF service. 400 Bad request means request parameter value which you are passing to method doesn't match with method's parameter. I have used Base64 string encoding to pass file as method parameter. May it'll help you.
On Android phone, I used setEntity() to put the FileEntity to the POST request.
HttpPost post = new HttpPost(uri);
FileEntity reqEntity = new FileEntity(f, "application/x-gzip");
reqEntity.setContentType("binary/octet-stream");
reqEntity.setChunked(true);
post.addHeader("X-AethersNotebook-Custom", configuration.getCustomHeader());
post.setEntity(reqEntity);
When using bottle, tried this but it is not working
f = request.body
gzipper = gzip.GzipFile( fileobj= f )
content = gzipper.read()
The content will be an empty string. So I tried to look at request.forms and request.files. Both of them have no key and value.
request.files.keys()
request.forms.keys()
When searching, I read about the entity: "a request MAY transfer entity" and the entity has entity-header and entity-value. So it may be something like file-content = e.get(entity-header).
Using that code, the phone send file using chunked encoding. Because py-bottle does not support chunked enconding, the solution here is rewrite the android to send file as body of POST request.
I have configured the apache httpClient like so:
HttpProtocolParams.setContentCharset(httpParameters, "UTF-8");
HttpProtocolParams.setHttpElementCharset(httpParameters, "UTF-8");
I also include the http header "Content-Type: application/json; charset=UTF-8" for all http post and put requests.
I am trying to send http post/put requests with a json body that contains special characters (ie. chinese characters via the Google Pinyin keyboard, symbols, etc.) The characters appear as gibberish in the logs but I think this is because DDMS does not support UTF-8, as descibed in this issue.
The problem is when the server receives the request, it sometimes doesn't see the characters at all (especially the Chinese characters), or it becomes meaningless garbage when we retrieve it through a GET request.
I also tried putting 250 non-ascii characters in a single field because that particular field should be able to take up to 250 characters. However, it fails to validate at the server side which claims that the 250 character limit has been exceeded. 250 ASCII characters work just fine.
The server dudes claim that they support UTF-8. They even tried simulating a post request that contains Chinese characters, and the data was received by the server just fine. However, the guy (a Chinese guy) is using a Windows computer with the Chinese language pack installed (I think, because he can type Chinese characters on his keyboard).
I'm guessing that the charsets being used by the Android client and the server (made by Chinese guys btw) are not aligned. But I do not know which one is at fault since the server dudes claim that they support UTF-8, and our rest client is configured to support UTF-8.
This got me wondering on what charset Android uses by default on all text input, and if it can be changed to a different one programatically. I tried to find resources on how to do this on input widgets but I did not find anything useful.
Is there a way to set the charset for all input widgets in Android? Or maybe I missed something in the rest client configuration? Or maybe, just maybe, the server dudes are not using UTF-8 at their servers and used Windows charsets instead?
Apparently, I forgot to set the StringEntity's charset to UTF-8. These lines did the trick:
httpPut.setEntity(new StringEntity(body, HTTP.UTF_8));
httpPost.setEntity(new StringEntity(body, HTTP.UTF_8));
So, there are at least two levels to set the charset in the Android client when sending an http post with non-ascii characters.
The rest client itself itself
The StringEntity
UPDATE: As Samuel pointed out in the comments, the modern way to do it is to use a ContentType, like so:
final StringEntity se = new StringEntity(body, ContentType.APPLICATION_JSON);
httpPut.setEntity(se);
I know this post is a bit old but nevertheless here is a solution:
Here is my code for posting UTF-8 strings (it doesn't matter if they are xml soap or json) to a server. I tried it with cyrillic, hash values and some other special characters and it works like a charm. It is a compilation of many solutions I found through the forums.
HttpParams httpParameters = new BasicHttpParams();
HttpProtocolParams.setContentCharset(httpParameters, HTTP.UTF_8);
HttpProtocolParams.setHttpElementCharset(httpParameters, HTTP.UTF_8);
HttpClient client = new DefaultHttpClient(httpParameters);
client.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_1);
client.getParams().setParameter("http.socket.timeout", new Integer(2000));
client.getParams().setParameter("http.protocol.content-charset", HTTP.UTF_8);
httpParameters.setBooleanParameter("http.protocol.expect-continue", false);
HttpPost request = new HttpPost("http://www.server.com/some_script.php?sid=" + String.valueOf(Math.random()));
request.getParams().setParameter("http.socket.timeout", new Integer(5000));
List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
// you get this later in php with $_POST['value_name']
postParameters.add(new BasicNameValuePair("value_name", "value_val"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters, HTTP.UTF_8);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String lineSeparator = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line);
sb.append(lineSeparator);
}
in.close();
String result = sb.toString();
I hope that someone will find this code helpful. :)
You should set charset of your string entity to UTF-8:
StringEntity stringEntity = new StringEntity(urlParameters, HTTP.UTF_8);
You can eliminate the server as the problem by using curl to send the same data.
If it works with curl use --trace to check the output.
Ensure you are sending the content body as bytes. Compare the HTTP request from Android with the output from the successful curl request.
how to upload the datas to webserver from android mobile.Please provide coding
I think this compiles:
HttpPut request = new HttpPut(<uri>);
request.setEntity(new ByteArrayEntity(<your data>));
HttpResponse response = HttpClient.execute(httpPut);
You might want to use the HttpPost instead of HttpPut and also specify the content type on the request.