Android: Sending a byte[] array via Http POST - android

I am able to do a POST of a parameters string. I use the following code:
String parameters = "firstname=john&lastname=doe";
URL url = new URL("http://www.mywebsite.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
connection.setRequestMethod("POST");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(parameters);
out.flush();
out.close();
connection.disconnect();
However, I need to do a POST of binary data (which is in form of byte[]).
Not sure how to change the above code to implement it.
Could anyone please help me with this?

Take a look here
Sending POST data in Android
But use ByteArrayEntity.
byte[] content = ...
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new ByteArrayEntity(content));
HttpResponse response = httpClient.execute(httpPost);

You could base-64 encode your data first. Take a look at the aptly named Base64 class.

These links might be helpful:
Android httpclient file upload data corruption and timeout issues
http://getablogger.blogspot.com/2008/01/android-how-to-post-file-to-php-server.html
http://forum.springsource.org/showthread.php?108546-How-do-I-post-a-byte-array

Related

Dont how to replace BasicValueNamePair as its deprecated

This is my code below trying to create a login page using PHP, mysql and xampp server. I am having problem with BasicValueNamePair as it is deprecated. I dont know how to replace with new code. Any help please
URL url = new URL("http://10.0.3.2/android_api/check.php");
HttpURLConnection urlConnection =(HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.connect();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
String res = IOUtils.toString(in, "UTF-8");
System.out.println(res + " Blu bluh");
// make sure the url is correct.
//add your data
nameValuePairs = new ArrayList<NameValuePair>(2);
// Always use the same variable name for posting i.e the android side variable name
// and php side variable name should be similar,
nameValuePairs.add(new BasicNameValuePair("Username",username.getText().toString().trim()));
//$Edittext_value = $_POST['Edittext_value'];
nameValuePairs.add(new BasicNameValuePair("Password",password.getText().toString().trim()));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
//Execute HTTP Post Request
response=httpclient.execute(httppost);
HttpURLConnection is derived from URLConnection so you can
use the addRequestProperty to include your name-value pairs.
urlConnection.addRequestProperty("Username",username.getText().toString());
See details here

ByteArray to HttpResponse

I've a server and a client. My server sends a HttpResponse in a text format. I'm able to receive the text at client. I need to convert back the text to HttpResponse object. Are there any opensource libraries or in-built java/Android mechanisms to do this?
All I've got is converting HttpResponse to text.
Try this way
ByteArrayOutputStream baos = new ByteArrayOutputStream();
response.getEntity().writeTo(baos);
byte[] bytes = baos.getBytes();
Then you could add the content to another HttpResponse object as follows:
HttpResponse response = httpClient.execute(new HttpGet(URL));
response.setEntity(new ByteArrayEntity(bytes));
Just do this using Apache Commons IO: http://commons.apache.org/proper/commons-io/
private byte[] receiveByteArrayData(HttpURLConnection httpURLConnection)
throws IOException
{
return IOUtils.toByteArray(httpURLConnection.getInputStream());
}
Sending byte[] data:
URL url = new URL("http://your.url.here:yourPortNumber/something");
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setDoInput(true);
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setRequestProperty("Content-Type", "application/octet-stream");
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setFixedLengthStreamingMode(bytes.length);
httpUrlConnection.connect();
httpUrlConnection.getOutputStream().write(bytes);
httpUrlConnection.getOutputStream().flush();
if (httpsUrlConnection.getResponseCode() == 200) //OK
{
System.out.println("successfully uploaded data");
}
httpUrlConnection.disconnect();
I got exactly what I want from
parse http response bytes in java
Thanks everyone for responses :)

post body empty when using httpclient on android

Context: In Android, when I use Java's HttpURLConnection object as shown below, I see the POST body correctly on the server side. However, when I use what I believe is the equivalent HttpClient code, the POST body is empty.
Question:
What am I missing?
Server-side is a Django-python server. I have set up a debug point at the entry point of this endpoint but the post body is already empty. How can I debug through it to find out why the body is null?
Note: I already looked at this , but the solution does not work for me.
Code: using HttpURLConnection - this works:
try {
URL url = new URL("http://10.0.2.2:8000/accounts/signup/");
String charset = "UTF-8";
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty ("Authorization", "Basic base64encodedstring==");
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=" + charset);
connection.setDoInput(true);
StringBuilder sb = new StringBuilder();
sb.append("appver=6&user=value1pw=&hash=h1");
OutputStreamWriter outputWriter = new
OutputStreamWriter(connection.getOutputStream());
outputWriter.write(sb.toString());
outputWriter.flush();
outputWriter.close();
// handle response
} catch () {
// handle this
}
============================================================
Code: using Apache httpclient - does NOT work - server gets empty POST body:
HttpPost mHttpPost = new HttpPost(""http://10.0.2.2:8000/accounts/signup/"");
mHttpPost.addHeader("Authorization", "Basic base64encodedstring==");
mHttpPost.addHeader("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
mHttpPost.addHeader("Accept-Charset", "UTF-8");
String str = "appver=6&user=value1pw=&hash=h1"; // same as the above
StringEntity strEntity = new StringEntity(str);
mHttpPost.setEntity(strEntity);
HttpUriRequest pHttpUriRequest = mHttpPost;
DefaultHttpClient client = new DefaultHttpClient();
httpResponse = client.execute(pHttpUriRequest);
// more code
I figured the reason why this was happening:
The authorization header in the POST request had an extra new line character "\n" - this was causing the request to go through to the server side handler, but with the body getting cut off. I have never noticed this behavior before.

calling RESTful WCFservice method with object as parameter from java

i have a RESTful WCF service and one of its methods use an Object as parameter
[WebInvoke(UriTemplate = "save", Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat= WebMessageFormat.Xml), OperationContract]
public SampleItem Create(SampleItem instance)
{
return new SampleItem() { Id = 1, StringValue = "saved" };
// TODO: Add the new instance of SampleItem to the collection
//throw new NotImplementedException();
}
I am trying to call this method from my eclipse android project. i am using these lines of codes
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost post=new HttpPost("http://10.0.2.2:2768/Service1.svc/save");
ArrayList<NameValuePair> nvp= new ArrayList<NameValuePair>();
nvp.add(new BasicNameValuePair("Id", "1"));
nvp.add(new BasicNameValuePair("StringValue", "yolo"));
post.setEntity(new UrlEncodedFormEntity(nvp));
HttpResponse httpResponse = httpClient.execute(post);
HttpEntity httpEntity = httpResponse.getEntity();
String xml = EntityUtils.toString(httpEntity);
Every time i get this error Method not allowed. in the XML that is returned by the service method.
i have tried invoking it from the browser, but encountered the same error there.
please tell me what i am doing wrong and what i can do instead.
thanks in advance to anyone who can help.
note: other methods which do not use object as parameter are working fine.
EDIT: tried Fiddler2 with success. but stalled again.
i have tried invoking the method SampleItem Create(SampleItem instance) with the url http://localhost:2768/Service1.svc/save and it works. the method returns the object in XML format.
in fiddler i added the request body as
<SampleItem xmlns="http://schemas.datacontract.org/2004/07/WcfRestService1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Id>1</Id><StringValue>saved</StringValue></SampleItem>
but the problem is that i can not find any way to add this xml string to the HttpPost or HttpRequest as the requestbody eclipse android project.
note: passing the xml string as Header or UrlEncodedFormEntity did not work.
finally i have succeeded to send a json object over to my WCF Service here's my code
URI uri = new URI("http://esimsol.com/droidservice/pigeonlibrary.service1.svc/save");
JSONObject jo1 = new JSONObject();
jo1.put("Id", "4");
jo1.put("StringValue", "yollo");
HttpURLConnection conn = (HttpURLConnection) uri.toURL().openConnection();
conn.setRequestProperty("Content-Type","application/json; charset=utf-8");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("User-Agent", "Pigeon");
conn.setChunkedStreamingMode(0);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.write(jo1.toString().getBytes());
out.flush();
int code = conn.getResponseCode();
String message = conn.getResponseMessage();
InputStream in = conn.getInputStream();
StringBuffer sb = new StringBuffer();
String reply;
try {
int chr;
while ((chr = in.read()) != -1) {
sb.append((char) chr);
}
reply = sb.toString();
} finally {
in.close();
}
SampleItem SI = new SampleItem();
SI=new Gson().fromJson(reply, SampleItem.class);
Toast.makeText(getApplicationContext(), SI.getStringValue(),Toast.LENGTH_LONG).show();
conn.disconnect();
thanks to StackOverFlow.
i had to combine a number of code snippets to achieve this.
First, you should get the Web Service method working from the browser - I recommend using Fiddler2 - its easier to construct the request body with your object and also to set the request headers when doing a post. It will show you the response so should help with debugging.
As for your code, I'm doing a POST to a WCF service and instead of doing
post.setEntity(new UrlEncodedFormEntity(nvp));
I'm simply doing:
HttpPost request = new HttpPost(url);
// Add headers.
for(NameValuePair h : headers)
{
request.addHeader(h.getName(), h.getValue());
}
(I am using JSONObjects and I have RequestFormat = WebMessageFormat.Json in my WebInvoke parameters.
Also, check your using the correct UriTemplate name in your url as they are case sensitive.
To call that WCF service you must build valid SOAP request and post it. It is better to use some SOAP protocol stack on Android - for example kSoap2.
Here is example of using kSoap2 to call WCF service.
just add KSOAP2 lib in your project.for how we add KSOAP2 in Android project see this post

Why connection is not establishing on first time?

I want to send my id & password to server and get the response from server. Here is my code. It is not working for the first time. But iam getting the response from server if i execute my application on second time. It is throwing "Post method failed: -1 null" on first time. Where iam wrong?? Why if() block is executing on first time?? could you please tell me.
HttpsURLConnection con = null;
String httpsURL = "https://www.abc.com/login";
String query = "id=xyz&password=pqr";
URL url = new URL(httpsURL);
con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", String.valueOf(query.length()));
con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setRequestProperty("User-Agent","Mozilla/4.0(compatible; MSIE 5.0; Windows 98; DigExt)");
con.setDoInput(true);
con.setDoOutput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(query);
output.close();
int respCode = con.getResponseCode();
if (respCode != HttpsURLConnection.HTTP_OK)
{
throw new Exception("POST method failed: " + con.getResponseCode()+ "\t" + con.getResponseMessage()); }
else {
//read the content from server
}
1/ It is recommanded to use apache HttpClient rather than URLConnection (see http://developer.android.com/reference/org/apache/http/impl/client/DefaultHttpClient.html)
2/ for login and password, why not use Http Authentication ? both basic and digest are supported by android.
3/ as for you problem, you don't close the underlying outputStream.
you should do:
OutputStream os = con.getOutputStream();
DataOutputStream output = new DataOutputStream(os);
output.writeBytes(query);
output.close();
os.close();
Check Server service validity with other technology and/or classic java. You didn say in your question if you succeed to discriminate the server from the issue.
from java doc ...getResponseCode returns -1 if no code can be discerned from the response (i.e., the response is not valid HTTP).
Java https post request example : http://www.java-samples.com/java/POST-toHTTPS-url-free-java-sample-program.htm
try to close your outputstream after querying the status and not before...that may help
Here is how you should send POST requests in Android
HttpPost httpGet = new HttpPost(server + "/login?email="+username+"&password="+password);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(httpGet);
You can read response using:
response.getEntity().getContent()

Categories

Resources