I am writing a program that downloads some HTML. I need to retain the original filenames and folder structure as are on the server, so I need a way to handle links like "www.google.com". If you type it in, it will obviously download some PHP, but I need to know exactly what that file is called. I am writing in Kotlin, but if you can provide an answer in Java that'll work.
I need to retain the original filenames and folder structure as are on the server
This not possible, you cannot know the structure of the data on the server. There may not even exist a file and folder structure on the server, the returned data could be all dynamically generated an not be based on a filesystem.
Related
I've been trying to do this in a liferay module project. By making an input type=file in my view.jsp and saving it in a java File variable but i can't get it to work. Is this possible? and if yes, how?
So far i've looked for a paramutil method that i can use but there don't seem to be any. And i've tried to use request.getParameter but this doesn't allow for the type File to be used. After that I tried to create a upload request and fill it with the data from the form. But this also didn't work for me.
I wanted to make a form in my jsp file and let people upload a file via the input and let my java code run on submit to add the file to the documentlibrary.
A java File (as in java.io.File) is an abstraction for a pointer to something sitting on your file system. When you upload data in a portlet or any other means in a web application, you're first dealing with a stream of data that usually has no representation on the hard drive (unless you explicitly store it there). Thus, ParamUtil will not reveal anything of type File, because that's - by definition - not part of a http request.
There is a lot of upload sample code, that you might need to adapt to the version you're running (for example this) - but you'll first need to understand that you're not looking for any representation of data on your hard drive.
I need to write a little Grails (or Java) app that will handle authentication (from our proprietary Single Sign On system) and then once authenticated allow a user to download files. This is very straight forward if I simply include the files in the WAR file of the application, however, I'd like to avoid that since there will be multiple files and I'd rather not have to upload a new WAR file every time we add a new file. Is it possible to accomplish this by having the application be in a WAR file but the files outside the WAR file, if so, how do I configure this kind of setup? We'll be running this on Tomcat.
Yes this is possible. Without knowing all your requirements or what you have tried and why it didn't work work for you the best I can do is give you a general idea of how to accomplish this.
Have a controller that takes an ID of the file that you want the user to download. Based on this key find the associated Domain instance. The domain should store the file name of the file. Then use this file name to resolve the file from the local file system (path configured in your application configuration). Open the file and stream the contents to the browser. Be sure to set he headers correctly to indicate the file name and size.
There are a lot of moving parts involved here but it can be done. Now, if you get stuck on something I suggest you post what you have tried and what's not working about it. Otherwise, the best we/I can do is give you general guidance/advice.
Hope this helps!
Edit
The real key is going to be in the controller for downloading the files. Here is a quick snippet of what that may look like:
String fileName = "something.zip" // should come from your domain instance
String filePathAndName = "/downloads/${fileName}" // should come from your configuration
response.setContentType("application/octet-stream")
response.setHeader("Content-disposition", "attachment;filename=${fileName")
// this will actually buffer/stream the file in 8k chunks instead of reading the entire file into memory.
org.apache.commons.io.IOUtils.copy((new File(filePathAndName)).openStream(), response.outputStream)
response.outputStream.flush()
response.outputStream.close()
So I'm writing a Spring web application that runs some scripts on the local server using ProcessBuilder. That part seems to be running fine. The scripts generate output files and then zip them up into a single .zip file. I'd like to provide the user with a way to download these files but I'm not sure of the best way to do this, or even how to implement any way to do it.
I tried putting the path to the directory into the URL, but I believe since Spring intercepts all URLs and it doesn't know how to process the one pointing at either the directory the Zip is in or the Zip itself, I just get an error. What would the proper way to do this be? Either to display a list of files or just link to the files themselves? Any help would be really appreciated, thank you.
The way you do any file download from a web-app is to write a servlet that writes the content of the file to the http response's output stream. There's an example of this here that's downloading an Excel file.
The directory listings that you get in a web-page don't just happen automatically, you'll have to write a JSP that displays the directory listing with hyperlinks on each file that link to file download servlet.
I looked around and could not find a complete directory listing example for spring. Though it is relatively simple to implement I put together a blog post to explain this, so that it could be quickly reused when needed http://krishna-passionatelycurious.blogspot.com/2013/04/file-download-page-using-spring.html.
But, the overall approach is to loop through the contents of a directory and generate appropriate links, such that the links point back to the same spring handler, where we could make a decision based on whether the accessed link actually points to a directory or a file and generate directory listing again or stream the content for download.
The blog has a sample implementation of this.
I am doing a project in java and in that i need to add and modify my
text file at runtime,which is grouped in the jar.
I am using class.getResourceAsStream(filename) this method we
can read that file from class path.
i want to write into the same textfile.
What is the possible solution for this.
If i can't update the text file in jar what other solution is there?
Appreciate any help.
The easiest solution here is to not put the file in the jar. It sounds like you are putting files in your jar so that your user only needs to worry about one file that contains everything related to that program. This is an artificial constraint and just add headaches.
There is a simple solution that still allows you to distribute just the jar file. At start up, attempt to read the file from the file system. If you don't find it, use default values that are encoded in you program. Then when changes are made, you can write it to the file system.
In general, you can't update a file that you located using getResourceAsStream. It might be a file in a JAR/ZIP file ... and writing it would entail rewriting the entire JAR file. It might be a remote file served up by a Url classloader.
For your sanity (and good practice), you should not attempt to update files that you access via the classpath. If you need to, read the file out of the JAR file (or whatever), copy it into the regular file system, and then update the copy.
I'm not saying that it is impossible to do this in all cases. Indeed, in most normal cases you can do it with some effort. However, this is not supported, and there are no standard APIs for doing this.
Furthermore, attempts to update resources are liable to cause anomalies in the classloader. For example, I'd expect resources in JAR files to not update (from the perspective of the application) until the application restarted. But resources in exploded JAR files probably would update ... though new resources might not show up.
Finally, there are cases where updating a resource is impossible:
When the user doesn't have write access to the application's installation directory. This is typical for a properly administered UNIX / Linux machine.
When the JAR file is fetched from a remote server, you are likely not to be able to write the updates back.
When you are using an arbitrary custom classloader, you've got no way of knowing where the actual bytes of an updated resource should be stored, and no way of storing them.
All JAR rewriting techniques in Java look similar. Open the Jar file, read all of it's contents, and write a new Jar file containing the unmodified contents (and the modifications you whished to make). Such techniques are not advisable for a Jar file on the class path, much less a Jar file you're running from.
If you decide you must do it this way, Java World has a few articles:
Modifying Archives, Part 1
Modifying Archives, Part 2
A good solution that avoids the need to put your items into a Jar file is to read (if present) a properties file out of a hidden subdirectory in the user's home directory. The logic looks a bit like this:
if (the hidden directory named after my application doesn't exist) {
makeTheHiddenDirectory();
writeTheDefaultPropertiesFile();
}
Properties appProps = new Properties();
appProps.load(new FileInputStream(fileInHiddenDir));
...
... After the appProps have changed ...
...
appProps.store(new FileOutputStream(fileInHiddenDir), "Do not modify this file");
Look to java.util.Properties, and keep in mind that they have two different load and store formats (key = value based and XML based). Pick the one that suits you best.
If i can't update the text file in jar what other solution is there?
Store the information in any of:
Cookies
The server
Deploy the applet using 1.6.0_10+, launch it using JWS and use the PersistenceService to store the information. Here is my demo. of the PersistenceService.
Also, if your users will agree to a trusted applet (which seems overkill for this), you might write the information to a sub-directory of user.home.
I need some ideas on how I can best solve this problem.
I have a JBoss Seam application running on JBoss 4.3.3
What a small portion of this application does is generate an html and a pdf document based on an Open Office template.
The files that are generated I put inside /tmp/ on the filesystem.
I have tried with System.getProperties("tmp.dir") and some other options, and they always return $JBOSS_HOME/bin
I would like to choose the path $JBOSS_HOME/$DEPLOY/myEAR.ear/myWAR.war/WhateverLocationHere/
However, I don't know how I can programatically choose path without giving an absolute path, or setting $JBOSS_HOME and $DEPLOY.
Anybody know how I can do this?
The second question;
I want to easily preview these generated files. Either through JavaScript, or whatever is the easiest way. However, JavaScript cannot access the filesystem on the server, so I cannot open the file through JavaScript.
Any easy solutions out there?
Not sure how you are generating your PDFs, but if possible, skip the disk IO all together, stash the PDF content in a byte[] and flush it out to the user in a servlet setting the mime type to application/pdf* that responds to a URL which is specified by a link in your client or dynamically set in a <div> by javascript. You're probably taking the memory hit anyways, and in addition to skipping the IO, you don't have to worry about deleting the tmp files when you're done with the preview.
*****I think this is right. Need to look it up.
Not sure I have a complete grasp of what you are trying to achieve, but I'll give it a try anyway:
My assumption is that your final goal is to make some files (PDF, HTML) available to end users via a web application.
In that case, why not have Apache serve those file to the end users, so you only need your JBOSS application to know the path of a directory that is mapped to an Apache virtual host.
So basically, create a file and save it as /var/www/html/myappfiles/tempfile.pdf (the folder your application knows), and then provide http://mydomain.com/myappfiles (an Apache virtual host) to your users. The rest will be done by the web server.
You will have to set an environment variable or system property to let your application know where your folder resides (/var/www/html/myappfiles/ in this example).
Hopefully I was not way off :)
I agree with Peter (yo Pete!). Put the directory outside of your WAR and setup an environment variable pointing to this. Have a read of this post by Jacob Orshalick about how to configure environment variables in Seam :
As for previewing PDFs, have a look at how Google Docs handles previewing PDFs - it displays them as an image. To do this with Java check out the Sun PDF Renderer.
I'm not sure if this works in JBoss, given that you want a path inside a WAR archive, but you could try using ServletContext.getRealPath(String).
However, I personally would not want generated files to be inside my deployed application; instead I would configure an external data directory somewhere like $JBOSS_HOME/server/default/data/myapp
First, most platforms use java.io.tmpdir to set a temporary directory. Some servlet containers redefine this property to be something underneath their tree. Why do you care where the file gets written?
Second, I agree with Nicholas: After generating the PDF on the server side, you can generate a URL that, when clicked, sends the file to the browser. If you use MIME type application/pdf, the browser should do the right thing with it.