I have deployed an application in Google App Engine and and I want to upload and download data from server using java code at desktop and server code for download request and one more: Where do I store the data in apps engine?
To store binary data (file contents) you have three options:
Blob property of Datastore entities
Blobstore
Google Cloud Storage
You can save your file anywhere on your server, you just need to know the path.
how i direct it as output stream?
Here is a code snippet that can help you.
File fileOnServer = new File("Hello.txt"); // Give full path where your file is located
byte[] file = new byte[(int) fileOnServer.length()];
FileInputStream fileInputStream = new FileInputStream(fileOnServer);
fileInputStream.read(file);
int contentLength = (int) file.length;
response.setContentLength(contentLength);
response.setHeader("Content-Disposition", "attachment; filename=\"Hello.txt\"");
out = response.getOutputStream();
int bytesWritten = 0;
byte[] buffer = new byte[1024];
while (bytesWritten < contentLength) {
int bytes = Math.min(1024, contentLength - bytesWritten);
System.arraycopy(file, bytesWritten, buffer, 0, bytes);
if (bytes > 0) {
out.write(buffer, 0, bytes);
bytesWritten += bytes;
} else if (bytes < 0);
}
get download to user end?
Well you can add ClickHandler on a Button on your client side and override onClick method.
public void onClick(ClickEvent event) {
Window.open("UrlToYourServelet", "_blank", "null");
}
Hope this helps!
EDIT
I have found a solution. You can upload the file at any free file hosting site like this. This site provides a URL for every uploaded file. So in your servelet, make a HTTP request to the URL and download the file in byte[] and write it on outputStream as shown in the code above.
Related
I am creating an app that allows the user to upload multiple files to my server and I am doing the uploading with the "Fast Android Networking" Library, so I will need to provide File Objects to upload the files and can not use the Uri's I get from the filechooser.
Currently I'm getting an InputStream from a Uri and copy it into a File.
public static void copyInputStreamToFile(InputStream inputStream,
File file) throws IOException {
try (FileOutputStream outputStream = new FileOutputStream(file, false)) {
int read;
byte[] bytes = new byte[8192];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
}
}
This though, will get any device to lag pretty fast and I'd like to avoid this. I searched everywhere but couldn't find a method for converting a Uri to a File object, that works for me. If anyone knows a way to directly upload from uri, that would also work for me.
I have a server-side application which download file from an external URL into the server. This happens on an async process. I will need to have a Ajax call to get the file download progress and report in UI.
This can be achieved by updating the file download progress into a DB in a defined interval and AJAX call can get progress from Database. But this will be DB resource intensive.
Another option (I'm not sure if this works) is to read the file downloading in progress to compare the size with the total Content-Length to get the % downloaded.
Is there any way to access the OutputStream from the async background process and return the upload % ?
The front end of the application is using AngularJS and backend is implemented using Spring Framework.
File Download code is generic:
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
I need to save a file and download file in directory outside server context.
I am using Apache Tomacat
I am able to do this in directory present in webapps directory of application
If my directory structure is as follows,
--src
--WebContent
-- uploaddir
-- myfile.txt
Then I am able to download in by simply.
download
But, problem is when file is in some other directory say d:\\uploadedfile\\myfile.txt
then I wont be able to download it, as resource is not in server context as above.
I have file path to uuid mapping,
like,
d:\\uploadedfiles\\myfile.txt <-> some_uuid
then I want file should be downloaded, on click of following,
download
So, How to make file downloadable when it is outside the server context,
I heard about getResourceAsStream() method which would do this , But would any one help me on how to do this, probably with simple code snippet?
Try the below code which you can write in filedownloadservet. Fetch the file name from the request parameter and then read and write the file.
If you need to do some security checks then do that before processing the request.
File file = new File("/home/files", "file name which user wants to download");
response.setContentType(getServletContext().getMimeType(file.getName()));
response.setContentLength(file.length());
BufferedInputStream inputStream = null;
BufferedOutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(file));
outputStream = new BufferedOutputStream(response.getOutputStream());
byte[] buf = new byte[2048];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
//log it
}
}
// do the same for input stream also
}
here i found the answer,
response.setContentType("application/msword");
response.setHeader("Content-Disposition","attachment;filename=downloadname.doc");
File file=new File("d:\\test.doc");
InputStream is=new FileInputStream(file);
int read=0;
byte[] bytes = new byte[BYTES_DOWNLOAD];
OutputStream os = response.getOutputStream();
while((read = is.read(bytes))!= -1){
os.write(bytes, 0, read);
}
os.flush();
os.close();
Base path will not work that is for HTML and it works if the base path is also exposed by your web server which does not look like case here.
To download an arbitary file you need to open the file using a FileInputStream (and surround it by a buffered input stream), read a byte, then send that byte from your servlet to the client.
Then there are security concerns, so should google that (basically not give access to any file but only file that is to be shared, audit download etc as needed.
Again in your servlet set the mime type etc and then open a input stream and write the bytes to the output stream to client
I wrote small program for downloading files via url. Every other files format I can open properly, but for downloaded pdf it's impossible.
public static void saveFile(String fileUrl, String destinationFile) throws IOException {
URL url = new URL(fileUrl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(destinationFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
os.flush();
is.close();
os.close();
}
Do I need special way for handling pdf downloads?
When I try to get selected pdf via URL in browser it's displays properly
EDIT
Added flush() to code, still no success
Trying to open damaged pdf in browser (FF) returns error:
File does not begin with '%PDF-'
Adobe Reader returns:
File could not be open because it is either not a supported file type
or because file has been damaged.
Damages pdf has smaller size (about 80%) than original
The damaged pdf files has website html code inside.
I have an Google App Engine (Java) based application which stores the file data in Google Cloud storage.
This file download servlet works fine in my local eclipse environment and when deployed to appspot domain, this works for simple text files but for any documents (displayed in the browser in a new tab), but if I try with any other binary files (doc, jpeg, gif etc) seem to do nothing, no error is thrown as well at the server side . I checked directly in the file folders in Google Cloud storage, files are stored properly and able to access it directly, but cannot do so via the app engine.
Can you please let me know if I am missing something?
The code snippet below,
try {
FileService newfileService = FileServiceFactory.getFileService();
AppEngineFile file = new AppEngineFile(cloudpath) ;
FileReadChannel channel = newfileService.openReadChannel(file, false);
BufferedInputStream bis = new BufferedInputStream(Channels.newInputStream(channel));
BufferedOutputStream bos = new BufferedOutputStream(resp.getOutputStream());
resp.setHeader("Content-Disposition", "inline;filename=\"" + file.getNamePart() + "");
int b = 0;
while((b = bis.read()) != -1) {
bos.write(b);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
}
Instead of trying to stream the file yourself you should use the BlobstoreService.serve method. This takes care or streaming and can be used on files of any size.
Something like
BlobstoreService blobService = BlobstoreServiceFactory.getBlobstoreService();
blobService.serve(blobService.createGsBlobKey(cloudpath), resp);
you'll try the following order of statements.
...
resp.setContentType("application/octet-stream");
resp.setHeader("Content-Disposition", "inline;filename=\"" + file.getNamePart() + "");
BufferedOutputStream bos = new BufferedOutputStream(resp.getOutputStream());
int b=0;
...