Where do I look for my HttpClient's respons' content-length? - android

I'm using Apache-Commons and downloading file content. Everything works perfectly, but I want to add a progress indicator for which I need the incoming file's content length.
In my debugger I can see that my InputStream has an object labled 'in' of type ContentLengthInputStream, and one of this object's properties is, in fact, the length of the file! However, I don't see a way to get TO that object in my code. InputStream doesn't have all that many methods and none of them get at this inner Object or pull any values from it.
Is there some alternate way to get to this header? I can see that the data is in there, but I'm stumped as to how to access it.
In case it's useful, here's a snippet of the call...
HttpClient client = new HttpClient();
filePost = new PostMethod(URL_PATH);
InputStream ret ;
responseCode = client.executeMethod(filePost);
ret = filePost.getResponseBodyAsStream();

Get content length from headers.
Header[] headers = response.getAllHeaders();
for(Header h:headers){
if(h.getName().equals("Content-Length")){
length = h.getValue();
break;
}
}
What's the “Content-Length” field in HTTP header?

Ah! Found it...
using my code above...
HttpClient client = new HttpClient();
filePost = new PostMethod(URL_PATH);
InputStream ret ;
responseCode = client.executeMethod(filePost);
ret = filePost.getResponseBodyAsStream();
//adding this here gets you the size of the incoming file
long fileSize = filePost.getResponseContentLength();

Related

Is it possible to post at the same time a string and an image to a webserver?

There is a string variable and an image photo taken from the camera intent. The directory location of the photo is known. I want to make a HTTP post of the string variable and the image photo to a webserver at the same time. Is that possible ? If so , how to do it ?
From what I understand, you need to send an image and a string to your webserver within a single POST request. Here's how you'd proceed.
You first need to Base64 encode your image.
Start by converting your image into a byte array:
InputStream image = new FileInputStream(<path_to_image>);
byte[] buff = new byte[8192];
int readBytes;
ByteArrayOutputStream byteArrOS = new ByteArrayOutputStream();
try {
while ( (readBytes = inputStream.read(buff) ) != -1) {
byteArrOS.write(buff, 0, readBytes);
}
} catch (IOException e) {
e.printStackTrace();
}
byte[] b = byteArrOS.toByteArray();
Then convert it to Base64:
String bsfEncodedImage = Base64.encodeToString(b, Base64.DEFAULT);
Then build a query with the the string and the resulting Base64 both encoded with URLEncoder and "utf-8":
strImgQuery = "str="+URLEncoder.encode(<string_data>, "utf-8")+"&image="+URLEncoder.encode(bsfEncodedImage, "utf-8");
Declare a new URL:
URL postUrl = new URL("http://<IP>/postreq");
Open the connection:
HttpURLConnection conn = (HttpURLConnection)postUrl.openConnection();
Set output to "true" (needed for a POST request but not for GET):
conn.setDoOutput(true);
Set the request method to POST:
conn.setRequestMethod("POST");
The timeout:
conn.setReadTimeout(1e4);
Buffer the output to the output stream and flush/run:
Writer buffWriter = new OutputStreamWriter(conn.getOutputStream());
buffWrite.write(strImgQuery);
buffWriter.flush();
buffWriter.close();
At server side you'll get the str and image POST params which is dependent on your server implementation.
Note that your url must follow the URL Specification, otherwise you'll get a MalformedURLException. If that's the case, be sure to check what exactly the issue is. For example if you use a non-existing ttp "protocol" instead of http your exception will look something like this:
java.net.MalformedURLException: unknown protocol: ttp
at java.net.URL.<init>(URL.java:592)
at java.net.URL.<init>(URL.java:482)
at java.net.URL.<init>(URL.java:431)
at com.pheromix.core.lang.NumberFormatExceptionExample.MalformedURLExceptionExample.sendGetRequest(MalformedURLExceptionExample.java:28)
at com.pheromix.core.lang.NumberFormatExceptionExample.MalformedURLExceptionExample.main(MalformedURLExceptionExample.java:17)
Also, this is a synchronous operation and is ran on the UI thread. It might be costly or it might not depending on other operations you're already running and the size of the POST data. If the problem arises, run the job on another thread.
You can use URLEncoder
String strUrl = "http://192.168.1.9/impots/" +URLEncoder.encode("outil.php?action=OutilImporterDonneesMobile", "utf-8");
URL url = new URL(strUrl);

File sent using HttpPost corrupted and/or truncated

I receive a file using the following code:
byte[] fileBytes;
....
JSONObject postJSON = new JSONObject();
postJSON.put("file_name", filename);
postJSON.put("client_id", clientID);
HttpPost post = new HttpPost(fileURL);
StringEntity se = new StringEntity( postJSON.toString(), "UTF-8");
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = httpClient.execute(post);
fileBytes = EntityUtils.toByteArray(response.getEntity());
Using the debugger, I see that the response gets an entity 27136 bytes in length, which is the correct length of the test file, but the fileBytes array is only 11470 bytes long. Can anyone tell my why this truncation is taking place? When I try to get other files, a similar truncation takes place, so it is not a function of the specific file or a specific file length.
Using the following code, I get 11997 bytes for the same file:
StringBuilder stringBuilder = new StringBuilder("");
stringBuilder.append(EntityUtils.toString(response.getEntity()));
fileBytes = stringBuilder.toString().getBytes();
Reading from an InputStream, I get 12288 bytes:
fileBytes = new byte[1024];
InputStream inputStream = response.getEntity().getContent();
int bytesRead = 0;
while(true){
bytesRead = inputStream.read(fileBytes);
if (bytesRead <= 0)
break;
....
}
Changing the encoding to UTF-16 gets me an internal server error.
I also tried the following:
InputStream inputStream = response.getEntity().getContent();
response.getEntity().getContentLength()];
while ((getByte = inputStream.read()) != -1) {
bos.write(getByte);
}
bos.close();
This also gave me a file of 11470.
In all cases, the files are corrupted, and cannot be opened. When compared in a binary file viewer, the firs 11 bytes match, and then the files diverge. I could not find any pattern in the corrupted file.
OK, the answer is apparently that all of the above are fine. The problem was with the server, which was not configuring the data stream correctly: Content-type was text/plain for all files, rather than application/pdf, and so on as appropriate.
My first clue was when we put a text file on the server, and it came over successfully. At that point I started working with the server side, and we figured it out pretty quickly.
Bottom line, if you are working on a server/client application, the problem might not be on your side.
I should have mentioned various posts which helped my construct the various versions that I collected above:
including this
and this
My apologies to various other helpful people whose posts I also looked at and up-voted.

Image download in android from server using jsp

I want to read an image using jsp and send over http to be accessed by an android application.
Code i tried for JSP is by adding data as header
String strDirectory = "D://abc.jpg";
File fp = new File(strDirectory);
int length = (int)fp.length();
buffer = new byte[length];
FileInputStream f0 = new FileInputStream(fp);
f0.read(buffer);
f0.close();
response.addHeader("image_data",new String(buffer));
I dont know if this is correct.
Whats the right way to send image bytes from a jsp page to android application
Don't think it is the right way honestly.
First of all i suggest you to use a servlet if you can otherwise
you have an implicit object called response and then
OutputStream os = response.getOutputStream();
byte[] buffer = new byte[1024];
while ( f0.read(buffer) != -1)
os.write(buffer);
.....
before this code you have to set correctly response header like:
response.setContentType("your contente type here");
Hope it helps you

What is the maximum size of HTTP Post method in android

What is the maximum size of android Post method? When I am getting responses from server, parts of the message are missing. I think it may have reached the maximum size of post method.
If there is no limit for post method, did I need to change my server specification for this?
I had the same problem, I used HttpPost and the response got from server but a part of data missed because of their very big size. That's why I used an other way : HttpURLConnection with OuputStream to send request to the server and BufferedReader/InputStream to get responses.
HttpURLConnection my_httpConnection = (HttpURLConnection) new URL("https://integrator-ut.vegaconnection.com/Authentication.svc?wsdl").openConnection();
my_httpConnection.setRequestMethod("POST");
my_httpConnection.setDoInput(true);
my_httpConnection.setDoOutput(true);
my_httpConnection.setRequestProperty("Content-type", "text/xml; charset=utf-8");
OutputStream my_outPutStream = this.my_httpConnection.getOutputStream();
Writer my_writer = new OutputStreamWriter(my_outPutStream);
my_writer.write(YOUR_REQUEST); //YOUR_REQUEST is a String
my_writer.flush();
my_writer.close();
BufferedReader my_bufferReader = new BufferedReader(new InputStreamReader(this.my_httpConnection.getInputStream()));
char[] buffer = new char[10000];
int nbCharRead=0;
try
{
while((nbCharRead = my_bufferReader.read(buffer, 0, 10000)) != -1)
{
/* Your treatement : saving on a file/arraylist/etc
}
}
Theoretically there isn't a limit. The POST response size is limited to Java VM Heap size which is device independent. It is probably more than your post response consumes.
How do you verify that part of your response is missing? If you print it out with LogCat or view it in debug mode, then you can see only the start of the message ending with three dots (all of the message is there, it isn't just displayed to you).

UTF8 Encoding in Android when invoking REST webservice

I'm invoking a rest WS that returns XML. Some elements have strings include special characters like áãç etc...
When I get the information via browser all of it is shown properly but when invoking it from Android I don't get the proper special characters.
Notice the 'decoded' and 'encoded' variables:
when I use
URLDecoder.decode(result, "UTF-8")
The result stays the same
when I use
URLEncoder.encode(result, "UTF-8") The result changes to what it would be expected (full of %'s symbols and numeric representing symbols and special characters).
Here's the method to call the webservice:
public void updateDatabaseFromWebservice(){
// get data from webservice
Log.i(TAG, "Obtaining categories from webservice");
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(ConnectionProperties.CATEGORIES_URI);
ResponseHandler<String> handler = new BasicResponseHandler();
String result = "";
String decoded;
String encoded;
try {
result = client.execute(request, handler);
decoded = URLDecoder.decode(result, "UTF-8");
encoded = URLEncoder.encode(result, "UTF-8");
String c = "AS";
} catch (Exception e) {
Log.e(TAG, "An error occurred while obtaining categories", e);
}
client.getConnectionManager().shutdown();
}
Any help would be appreciated
Use this to get xml string, assuming the server encodes data in UTF-8:
HttpResponse response = client.execute(request);
... // probably some other code to check for HTTP response status code
HttpEntity responseEntity = response.getEntity();
String xml = EntityUtils.toString(responseEntity, HTTP.UTF_8);
Uh. URLDecoder and encoder are for encoding and decoding URLs, not XML content. It is used for URL you use when making requests. So code is just... wrong.
But even bigger issue is that you are taking a String, whereas content is really XML which needs to be parsed. And for parser to do proper decoding of UTF-8 (and handling of entities etc), you would be better of getting a byte[] from request, passing that to parser; although asking http client to do decoding may work ok (assuming service correctly indicates encoding used; not all do -- but even if not, XML parsers can figure it out from xml declaration).
So: remove URLDecoder/URLEncoder stuff, parser XML, and extract data you want from XML.

Categories

Resources