how to monitor progress of uploading file in servlet 3.1 - java

i want to monitor the progress of the file which is getting uploaded
i m using servlet 3.1
i know that by the specs of servlet 3.1 , i don't need apache common fileUpload
i can do that only by the Part class
i did this
InputStream inputStream = null;
double s;
String size=null;
String contentType=null;
String submittedName=null;
String tim=null;
String actualLocation=null;
System.out.println("getting it also here");
Part filePart = request.getPart("file");
System.out.println("getting it here");
if(description.equals(""))
{
System.out.println("please provide some description about file");
}
else{
if (filePart != null )
{
s=(double)filePart.getSize();
double MB=(s/1048576);
if(MB != 0)
{
size=String.valueOf((float)MB);
contentType=filePart.getContentType();
submittedName=getFormatted(filePart.getSubmittedFileName());
tim=String.valueOf(System.currentTimeMillis());
actualLocation=name+"-"+commun+"-"+tim+"-"+submittedName;
System.out.println("getting it there");
inputStream = filePart.getInputStream();
System.out.println("getting it here & there");
try
{
File file=new File(x,actualLocation);
Files.copy(inputStream, file.toPath());
}
i know i can use a listener to monitor the progress , but the main question is that where should i set progress listener
i thought it should be set with Part filePart.before System.out.println("getting it here")
this is a screenshot of my project
u can see that chrome is displaying the progress of uploading (in the bottom)(but i want a much more impressive progress bar)
when i ran my project i thought that in the console i'll see "getting it also here " while uploading but i found that control is not coming to that part unless uploading is completed.
i'm a bit confuse at which segment the uploading is happening and where should i set progress listener

You don't need to do anything in server side for upload progress bar. You can do that just using javascript, html and css.
If you are using jQuery take a look at this pugin http://malsup.com/jquery/form/. Here is a file upload progress bar demo link http://malsup.com/jquery/form/progress.html. There are two more demos and plenty more examples in the website.
And you can take a look at this tutorial http://codular.com/javascript-ajax-file-upload-with-progress for doing this with html5 and javascript. Just ignore the PHP part.
You should not have to change anything in your java code, cause the servlet method will be hit after the file upload has been completed.

Related

JavaFX WebView Downloading

I'm trying to add downloads to my Web Browser but the problem I got is to get the name of the file that you're trying to download. This is my code for downloading:
engine.locationProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
File file = new File(System.getProperty("user.home") + "/Downloads/Ekko Downloads/");
String[] downloadableExtensions = {".doc", ".xls", ".zip", ".exe", ".rar", ".pdf", ".jar", ".png", ".jpg", ".gif"};
for(String downloadAble : downloadableExtensions) {
if (newValue.endsWith(downloadAble)) {
try {
if(!file.exists()) {
file.mkdir();
}
File download = new File(file + "/" + newValue);
if(download.exists()) {
Dialogs.create().title("Exists").message("What you're trying to download already exists").showInformation();
return;
}
Dialogs.create().title("Downloading").message("Started Downloading").showInformation();
FileUtils.copyURLToFile(new URL(engine.getLocation()), download);
Dialogs.create().title("Download").message("Download is completed your download will be in: " + file.getAbsolutePath()).showInformation();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
});
The problem is here: File download = new File(file + "/" + newValue);
Instead of that newValue i need to get the name of that file.
Ideally what you would be doing is intercepting calls at the network layer, and interpreting the content disposition MIME messages embedded in the HTTP traffic. Those messages can instruct the browser to download the file as an attachment with a provided filename. That is how you end up with some files being automatically downloaded based on an instruction sent from the server when you click on a link a browser.
Another thing browsers do is implement a kind of mime magic where they look at either the mime content type of the returned message, a deep inspection of the network traffic or just the extension prefix of a URL location to invoke a handler to download specific content types (you are doing only the later in your code).
The last way browsers handle downloads is you can right click on a page or link and choose Save As.
So, if you wanted a really robust fully functional browser like Chrome or Firefox you would do all of the above. As this horribly complicated test matrix shows, it is not really a particularly easy thing to do for all corner cases and even the big guys get it wrong.
Intercepting network traffic for WebView is possible but difficult. You can research other StackOverflow questions to do that - I won't address it here.
The same is also true of intercepting arbitrary web clicks, again search StackOverflow and it will turn up some questions on that, which might allow you to get right click to download functionality working.
So you are left with just intercepting location property changes as you are doing - obviously not ideal, but workable for many scenarios. That means you don't get filenames encoded in the content-disposition header, instead you have to parse the location url (just grab everything after the last /) and set that as the filename.
You can use the answers to the following question to derive the filename from the location URL:
Get file name from URL
The WebView in JavaFX 8.0 will change status to "CANCELLED" when it cannot display a web page. This is generally an indication of a downloadable file, and you can inspect the location to make sure or filter what you want to download.
Next you can create a URL out of the location and do an HTTP HEAD request. This will allow you to get possible options for the filename based of the HTTP headers sent back. The headers may contain a header called Content-Disposition and the content may contain something like the following: attachment; filename="somfilename.ext".
So basically from there you can determine if you want to use the filename in the URL or the filename specified in the Content-Disposition header.

Webapplication: Delete files during runtime

I am developing a webapp (for mobile phones). There is one xhtml page, where I want to show a picture, which is stored locally on my hard drive (for example: D:\pictures\test.jpg).
Since browsers block images when they are located on a local harddrive, I wrote a method in my javabean, where the picture, stored on the localHD, is copied to the webApp directory, when the user enters the xhtml page. After the user leaves the page, the copied file inside the webapp should be deleted.
So when I'm running my app, copying works perfectly and the pictures are displayed correctly. However, when the files should get deleted, I get this errormessage:
java.nio.file.FileSystemException: D:\WebAppPath\src\main\webapp\resources\pics\test.jpg:
The process cannot be accessed because the file is being used by another process.
Strangely enough, after stopping and restarting the application I can delete the same image if it is still in the webApp directory. (But Only once; after re-copying it, I get the error message again.)
Also if I want to delete the file manually, by using Windows explorer, I get the error message that the file can't be deleted because it is used by Java(TM) Platform SE Binary.
So to delete the file (manually or via the bean) I have to wait for a restart of the application, which of course is not an acceptable solution for the end user.
I'm using JSF2.0 with Primefaces and Primefaces Mobile components. My IDE is Netbeans and I use Spring Webflow framework to navigate and trigger actions/methods between the xhtml pages.
Here's the code for the copying method in my JavaBean:
public void copyFotoToLocalhost() {
if (fotoList.size() > 0) {
for (int i = 0; i < fotoList.size(); i++) {
Foto tempPic = fotoList.get(i);
String tempItemName = tempPic.getItemName();
String originalFile = "D:\\localFilepath\\" + tempItemName;
String tempFileName = "D:\\WebAppPath\\src\\main\\webapp\\resources\\pics\\" + tempItemName;
File existTest = new File(tempFileName);
if (existTest.exists() == false) {
try {
File orFile = new File(originalFile);
File tempFile = new File(tempFileName);
InputStream in = new FileInputStream(orFile);
OutputStream out = new FileOutputStream(tempFile);
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
tempFile.setWritable(true);
System.out.println("File copied.");
} catch (FileNotFoundException ex) {
System.out.println(ex.getMessage() + " in the specified directory.");
System.exit(0);
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
}
Here's the code for the delete method:
public void deleteFotos() {
if (fotoList.size() > 0) {
for (int i = 0; i < fotoList.size(); i++) {
Foto tempPic = fotoList.get(i);
String tempItemName = tempPic.getItemName();
Path tempLocation = Paths.get("D:\\webAppPath\\src\\main\\webapp\\resources\\pics\\" + tempItemName);
fotoList.remove(i);
i--;
try {
Files.deleteIfExists(tempLocation);
System.out.println("sucessfully deleted" + tempPic.getItemName());
} catch (IOException ex) {
Logger.getLogger(WundDokuBean.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Fail # " + tempPic.getItemName());
}
}
fotoList.clear();
}
Do you have an idea, how to fix this?
I hope you understand my problem, if not please tell me which information you need, I'll try to provide it.
There is one xhtml page, where I want to show a picture, which is stored locally on my hard drive (for example: D:\pictures\test.jpg). Since browsers block images when they are located on a local harddrive (...)
I want to clear out a conceptual misunderstanding first: You seem to expect that it would work fine when the browser wouldn't have blocked it. This is completely untrue. You seem to expect that images are inlined in the HTML output. No, they are downloaded individually and independently from the HTML page. If you had continued to use local disk file system paths, then it would have worked only and only if your webpage visitor has also exactly the same file at exactly the same location at their disk file system. In reality, this is obviously not the case. It would only work if both the webbrowser and webserver runs at physically the same machine.
Coming back to your concrete problem of being unable to delete the file, it's is caused because the servletcontainer usually locks the files in expanded WAR folder. I can't tell the exact reason, but that's not relevant here as this whole approach is wrong anyway. This approach would fail when the deployed WAR file is not expanded on disk file system, but instead in server's memory. Also, hardcoding environment-specific disk file system paths is a bad idea. You'd need to edit, rewrite, recompile, rebuild the whole WAR everytime you change the environment. In other words, your webapp is not portable.
You need to keep the files there where they originally are and make them publicly available by a real URL. This can be achieved in 2 general ways:
Add a virtual host to the server config, pointing to D:\localFilepath\. How to achieve that depends on the server used. You didn't tell anything about the server make/version used, but using Spring suggests that you're not being able to use full Java EE stack and are likely using a barebones JSP/Servlet container such as Tomcat. In that case, it's a matter of adding the following line to its /conf/server.xml:
<Context docBase="D:\localFilepath" path="/fotos" />
This way they are available by http://localhost:8080/fotos/*.
Create a servlet which reads files from D:\localFilepath and writes to HTTP response. With Servlet 3.0 and Java 7 it's really a breeze. Here's a kickoff example (nullchecks/file-exist-checks/doHead()/caching/resuming omitted for brevity):
#WebServlet("/fotos/*")
public class FotosServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExcpetion, IOException {
File file = new File("D:/localFilepath", request.getPathInfo().substring(1));
response.setHeader("Content-Type", getServletContext().getMimeType(file.getName()));
response.setHeader("Content-Length", String.valueOf(file.length()));
Files.copy(file.toPath(), response.getOutputStream());
}
}
That's basically it. This way they're available on http://localhost:8080/contextname/fotos/*.

Java file upload using Oreilly Multipartrequest

I'm doing a java web application that manage online auctions. At a certain point in the application the user can sell a product, so I have built a page where there is a form; in this form I have to handle the file upload using Oreilly Multipartrequest library. When I click the submit button a servlet should handle all the parameters, add the product on the database, and then redirect to the users page, but instead of doing it, the application hangs in a blank page. I'm using netbeans so I have checked the logs, but I can't find any errors; I have also checked on the logs inside the tomcat folder, but again I can't any errors. I don't know what to do neither where to search the solution.
Here is the part of the code that handle the upload:
try {
MultipartRequest multi =
new MultipartRequest(request, getServletContext().getRealPath("/img"), 10*1024*1024,
"ISO-8859-1", new DefaultFileRenamePolicy());
Enumeration files = multi.getFileNames();
while (files.hasMoreElements()) {
name = (String)files.nextElement();
filename = multi.getFilesystemName(name);
// String originalFilename = multi.getOriginalFileName(name);
// String type = multi.getContentType(name);
File f = multi.getFile(name);
if (f != null) {
session.setAttribute("success", "file written correctly");
}
}
} catch (IOException IEx) {
this.getServletContext().log("Error reading saving file");
}
Am I doing something wrong, or my idea is correct?
P.S. If the user decide not to upload any picture, I have to put on the database a default picture.

Generating a dynamic file and download it in GWT

I am developing a GWT application. This application is running in a server. Well, I implement a button which calls a method that generates a local file in server side. However I would like to download/generate this file in client side. How could I do this in GWT?
Thanks
In our project we created a file on server on demand. When the file has been successful created we send notification to browser and created a link.
See servlet code:
public class DownloadServlet extends HttpServlet {
private FileManager fileManager;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String encodedFileName = req.getRequestURI().substring(
req.getContextPath().length() + req.getServletPath().length() + 1);
String decodedFileName = URLDecoder.decode(encodedFileName, "utf-8");
File downloadableFile = fileManager.toFile(decodedFileName);
ServletOutputStream os = resp.getOutputStream();
try {
InputStream is = FileUtils.openInputStream(downloadableFile);
try {
IOUtils.copy(is, os);
} finally {
is.close();
}
} finally {
os.close();
}
}
}
private native void Download(String filename, String text)/*-{
var pom = document.createElement('a');
pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
document.body.appendChild(pom);
pom.click();
document.body.removeChild(pom); }-*/;
Use JSNI method inside GWT code , provide the file name you want to download in addition to JSON string as text (String) , this method will download a file with specified content in text variable to client browser.
Current situation is, that not all browsers are able to work with local file system, so there is no universal solution in GWT. Also as far as I know FilesSstem API is not finished.
As alternative you can keep using serverside generated files, or use Flash plugin to generate and store files (you will have to create a Flash app, and create some API to control it from GWT).
You should definitely have a look at Aki Miyazaki’s HTML5 file download code for GWT.
It works on the client side as you requested.
AFAIK, as of now, it only works in Chrome, but this is supposed to change as other browsers implement the download attribute.
You can do that using Data URIs:
Make your GWT RPC method return the file content or the data to generate the file.
On the client side, format a Data URI with the file content received or generate the data content.
Use Window.open to open a file save dialog passing the formatted DataURI.
Take a look at this reference, to understand the Data URI usage:
Export to csv in jQuery

Java URL problem

A webpage contains a link to an executable (i.e. If we click on the link, the browser will download the file on your local machine).
Is there any way to achieve the same functionality with Java?
Thank you
Yes there is.
Here a simple example:
You can have a JSF(Java Server Faces) page, with a supporting backing bean that contains a method annotated with #PostConstruct This means that any action(for example downloading), will occur when the page is created.
There is already a question very similar already, have a look at: Invoke JSF managed bean action on page load
You can use Java's, URL class to download a file, but it requires a little work. You will need to do the following:
Create the URL object point at the file
Call openStream() to get an InputStream
Open the file you want to write to (a FileOutputStream)
Read from the InputStream and write to the file, until there is no more data left to read
Close the input and output streams
It doesn't really matter what type of file you are downloading (the fact that it's an executable file is irrelevant) since the process is the same for any type of file.
Update: It sounds like what you actually want is to plug the URL of a webpage into the Java app, and have the Java app find the link in the page and then download that link. If that is the case, the wording of your question is very unclear, but here are the basic steps I would use:
First, use steps 1 and 2 above to get an InputStream for the page
Use something like TagSoup or jsoup to parse the HTML
Find the <a> element that you want and extract its href attribute to get the URL of the file you need to download (if it's a relative URL instead of absolute, you will need to resolve that URL against the URL of the original page)
Use the steps above to download that URL
Here's a slight shortcut, based on jsoup (which I've never used before, I'm just writing this from snippets stolen from their webpage). I've left out a lot of error checking, but hey, I usually charge for this:
Document doc = Jsoup.connect(pageUrl).get();
Element aElement = doc.getElementsByTag("a").first() // Obviously you may need to refine this
String newUrl = aElement.attr("abs:href"); // This is a piece of jsoup magic that ensures that the destination URL is absolute
// assert newUrl != null
URL fileUrl = new URL(newUrl);
String destPath = fileUrl.getPath();
int lastSlash = destPath.lastIndexOf('/');
if (lastSlash != -1) {
destPath = destPath.substring(lastSlash);
}
// Assert that this is really a valid filename
// Now just download fileUrl and save it to destPath
The proper way to determine what the destination filename should be (unless you hardcode it) is actually to look for the Content-Disposition header, and look for the bit after filename=. In that case, you can't use openStream() on the URL, you will need to use openConnection() instead, to get a URLConnection. Then you can use getInputStream() to get your InputStream and getRequestProperty("Content-Disposition") to get the header to figure out your filename. In case that header is missing or malformed, you should then fall-back to using the method above to determine the destination filename.
You can do this using apache commons IO FileUtils
http://commons.apache.org/io/apidocs/org/apache/commons/io/FileUtils.html#copyURLToFile(java.net.URL, java.io.File)
Edit:
I was able to successfully download a zip file from source forge site (it is not empty), It did some thing like this
import java.io.File;
import java.net.URL;
import org.apache.commons.io.FileUtils;
public class Test
{
public static void main(String args[])
{
try {
URL url = new URL("http://sourceforge.net/projects/gallery/files/gallery3/3.0.2/gallery-3.0.2.zip/download");
FileUtils.copyURLToFile(url, new File("test.zip"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I was able successfully download tomcat.exe too
URL url = new URL("http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.16/bin/apache-tomcat-6.0.16.exe");

Categories