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
Related
In my android application , user can upload a 300kb image;
I'm going to use This ( Android Asynchronous Http Client ) which I think is great and also Whatsapp is one of it's users.
In this library , I can use a RequestParams ( which is provided by apache I think) , and add either a file to it or an string ( lots of others too).
here it is :
1- Adding a file which is my image ( I think as a multipart/form-data)
RequestParams params = new RequestParams();
String contentType = RequestParams.APPLICATION_OCTET_STREAM;
params.put("my_image", new File(image_file_path), contentType); // here I added my Imagefile direcyly without base64ing it.
.
.
.
client.post(url, params, responseHandler);
2- Sending as string ( So it would be base64encoded)
File fileName = new File(image_file_path);
InputStream inputStream = new FileInputStream(fileName);
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
while ((bytesRead = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
bytes = output.toByteArray();
String encoded_image = Base64.encodeToString(bytes, Base64.DEFAULT);
// then add it to params :
params.add("my_image",encoded_image);
// And the rest is the same as above
So my Question is :
Which one is better in sake of Speed and Higher Quality ?
What are the differences ?
NOTE :
I've read many answers to similar questions , but none of them actually answers this question , For example This One
Don't know if params.put() and params.add would cause for a change of multipart encoding.
The base64 endoded data would transfer 30% slower as there are 30% more bytes to transfer.
What you mean by quality i do not know. The quality of the uploaded images would be equal as they would be byte by byte the same to the original.
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.
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();
I can't find an example of a simple FTP access of a file anywhere, and the FTPClient class (which a couple of examples use) doesn't appear in the Android Class Index. I've got http access working, but how do I do a simple FTP get? All I want to do is download (for example):
ftp://tgftp.nws.noaa.gov/data/observations/metar/stations/KABQ.TXT
It shouldn't require login, change directory, etc.
Just giving that URL to the http access methods don't seem to work.
This is similar to the question at:
unable to read file from ftp in android?
I tried a simple:
StringBuilder response = new StringBuilder();
URLConnection ftpConn;
try {
URL netUrl = new URL("ftp://tgftp.nws.noaa.gov/data/observations/metar/stations/KABQ.TXT");
ftpConn = netUrl.openConnection();
BufferedInputStream bufRd = new BufferedInputStream(ftpConn.getInputStream());
int temp;
while ((temp = bufRd.read()) != -1) {
response.append(temp);
}
bufRd.close();
} catch (Exception e) {
return "Failure";
}
but it gets an exception on getInputStream:
Unable to connect to server: Unable to configure data port
Also, there must be a more intelligent way to pull the data out of the stream buffer than byte-by-byte, isn't there? I can't find that either.
Lastly, I need to do both http and ftp access, is there any reason not to use URLConnection for both access types? or is it better to use HttpConnection for http and URLConnection for ftp?
Thanks!
Whew! I finally got it going. I gave up on the simple way that works in webOS and WPF/C# where you can just do a ftp:://... you have to use the FTPClient package.
After fixing the library access (Project | Properties | Java Build Path | Libraries | Add JARs...) I fiddled with the calls until it started working. Here's the sequence of my FTPClient calls. It wouldn't work until I set it in passive mode.
mFTPClient = new FTPClient();
mFTPClient.connect("tgftp.nws.noaa.gov");
mFTPClient.login("anonymous","nobody");
mFTPClient.enterLocalPassiveMode();
mFTPClient.changeWorkingDirectory("/data/forecasts/taf/stations");
InputStream inStream = mFTPClient.retrieveFileStream("KABQ.TXT");
InputStreamReader isr = new InputStreamReader(inStream, "UTF8");
And I also found on the web someplace an answer to the 'byte-by-byte' question. This seems to work to convert an InputStream type directly to String type:
String theStr = new Scanner(inStream).useDelimiter("\\A").next();
I also looked for a simple ftp download example without using of 3rd party libs. Didn't find any, so post my solution here.
URLConnection by default uses user name 'anonymous' with empty password which is not accepted by many ftp servers, as they require e-mail as the password for 'anonymous'.
To use the following code in your app, just add try..catch and make sure that reading from stream isn't block UI thread.
URL url = new URL("ftp://ftp.mozilla.org/README");
URLConnection cn = url.openConnection();
cn.setRequestProperty ("Authorization", "Basic " + Base64.encodeToString("anonymous:a#b.c".getBytes(), Base64.DEFAULT));
final File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
FileOutputStream fos = new FileOutputStream(dir.getPath() + "/README");
InputStream is = cn.getInputStream();
int bytesRead = -1;
byte[] buf = new byte[8096];
while ((bytesRead = is.read(buf)) != -1) {
fos.write(buf, 0, bytesRead);
}
if(is != null)is.close();
if(fos != null){ fos.flush(); fos.close(); }
Hope this will save you some time.
I want to send down a webpage from a server to WebView components on Android handsets.
I've already learned how to enable the webpage to talk to the JavaScript handler, so the native application can interact with the webpage.
I am, however, stuck on images.
I want the webpage that comes from a server to somehow tell the app which image (stored in either res or in assets) to load. This way I don't have to send the image over the wire as well. Is this doable? It will make the process of loading WebView pages so much faster for my purposes.
Thanks!
You can fetch the http response from the remote url, parse it and replace the remote image urls with local ones via string replace. Then use this html code to display in the webview.
I want to send down a webpage from a server to WebView
Are you talking about 'push' rather than 'pull' mechanism (like as usual with loadUrl())? That's only available in 2.2
(Question: I guess working entirely with local web pages on the device doesn't work in your case, since you need updated versions from the server, right? You only know that the images won't change, correct?)
Sample code for fetching a remote html page - afterwards you'd do the string replacement for your image urls:
/**
* Downloads a remote file and stores it locally
* #param from Remote URL of the file to download
* #param to Local path where to store the file
* #throws Exception Read/write exception
*/
static private void downloadFile(String from, String to) throws Exception {
HttpURLConnection conn = (HttpURLConnection)new URL(from).openConnection();
conn.setConnectTimeout(15000); // timeout 15 secs
conn.setDoInput(true);
conn.connect();
InputStream input = conn.getInputStream();
FileOutputStream fOut = new FileOutputStream(to);
int byteCount = 0;
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = input.read(buffer)) != -1) {
fOut.write(buffer, 0, bytesRead);
byteCount += bytesRead;
}
fOut.flush();
fOut.close();
}
Alternatively you could use
HttpClient httpClient = new DefaultHttpClient();
HttpGet get = new HttpGet("http://www.myurl.com");
HttpResponse res = httpClient.execute(get);
if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
InputStream input = res.getEntity().getContent();
byte data[] = new byte[14];
input.read(data);
....