Creating a storage for images directly in tomcat folder (Java) - java

I searched around the web and here and couldn't find a conclusive answer to this rather simple question. I am using Java+MySQL+HTML and CSS.
I created a webapp, and in this webapp the user can upload the photos path to the database .At the same time I am creating a folder completely outside of tomcat to copy inserted images there. The folder is on my desktop as I am on localhost, but I want to make the storage on the server not on my desktop.
After checking stackoverflow I saw that it is bad to store photos/images in tomcats webapp/AppName folder because this will overwrite the images all the time at redeployment which I don't want to do.
My tomcat folder is on desktop. Can I create a folder to store the images for this specific app here:
\Desktop\ApacheTomcat\apache-tomcat-9.0.24\ ?
The folder would be called TripAppImages like \Desktop\ApacheTomcat\apache-tomcat-9.0.24\TripAppImages and will be besides all of tomcats other folders like bin, conf, etc. I will also use this folder to display the images that the user inserted , back to him in a html page.
EDIT: ok so I have finally come upon a message from here how to create a folder in tomcat webserver using java program? from BalusC which says:
"Please note that you shouldn't store the files in the expanded WAR folder, or they will get lost every time you redeploy the webapp. Store them on a fixed path outside Tomcat's /webapps folder."
This I believe means that I can store the images like this \Desktop\ApacheTomcat\apache-tomcat-9.0.24\TripAppImages. As long ass they are not in the webapp folder it means they won't be overwritten.

The only folders you should avoid are temp, webapp, work and its subfolders, because yes, those folders can have its content replaced or deleted during deploys and cleanings, every other folder inside tomcat can be considered as 'just a folder' that, if you don't modify its contents, you can use the way you want. Of course it would not be normal or standard to, for example, store videos inside Tomcat\bin but if you don't touch the original files there you can do it.
So technically speaking, you can create a folder like \Desktop\ApacheTomcat\apache-tomcat-9.0.24\icecream and put images there it will not be erased or replaced by a deploy.
If it is just for you, temporary or not production, just avoid the three folders mentioned at the beginning and you are good to go.

Related

GAE: hiding sensitive website files / information

My website on GAE (Java 8 Environment) is working fine. However, I found out that files that are not in the WEB-INF folder, is accessible by the public simply by opening it in the browser e.g. https://example.net/resources/file.txt.
Several files, including javascript files, contain sensitive and security information that I wish to make inaccessible to the public. How do I this?
I had issues putting them in the WEB-INF folder since I couldn't figure out the proper way to reference them for the website to use e.g. < script >relative path to web-inf folder + resource< /script >.
If I could be taught to use WEB-INF properly, I would accept that as an answer to this question as well.
Edit:
There's some need for clarification. What I need to protect are the resource files. I understand that scripts need to be publicly accessible, in order for them to execute on the client side, though it would be great if I could somehow put them in the WEB-INF folder while still having them accessible for the site's execution.
But ultimately, if there was a method to fetch info from resources in the WEB-INF folder, via Javascript (or whatever can do the job outside a Servlet), then this will solve my issue. The resources are simply files containing text like keys, certain email addresses etc.

The easy and modern way to manage the changes of a java project on a deployment server

This is i am writing doubting that whether the method i am using outdated or not. I have a java webserver and usually i will have changes on and when i need to upload the changes i will build the project locally and upload java files and restart.
The other method is upload war file completely and place into webapps folder. In this case if there is any dynamic images or files uploaded by users, i need to take a backup and replaced with the newly created folder after the war file deployment.
Is the both above are good method or anybody can suggest me an even more good method to manage my live environment changes.

On the resources (classpath) folder and database.

I'm wondering if it is ok to use your resource folder as a database folder. I have a an application that run a small semantic database. Most of the work is done in memory but from time to time i need to commit the data in the database. It also saves the data, for when the program will be restarted again. I'm asking this because it sounds weird to me to have a growing Jar/bundle. Indeed, by default sbt or maven, put your resources in your jar/bundle.
Can someone enlighten me a bit about how to properly use the resources folder. Shall it be read only ?
AFAIK you can't overwrite files that are in .jar from code. But you could create a file in same location to save any data (and use default data if file does not exist).
Resources should be considered read-only, as the entire application could reside in a .jar. Also some resources are cached.
However you may use a database as resource for an initial database template. This you can copy to a subdirectory of the user's home, which also makes this application multi-user / multi-tenant.
InputStream dbIn = SomeClassInJar.class.getResourceAsStream("/data/initial.hdb");
Path dbPath = Paths.get(System.getProperty("user.home"), ".myapp", "db.hdb");
Files.createDirectories(dbPath.getParent()); // .myapp
Files.copy(dbIn, dbPath, StandardCopyAction.REPLACE_EXISTING);
The REPLACE_EXISTING maybe not to use.

Servlet : What exactly the use of context.getRealPath(" ");

As i know it returns the application path? But what exactly the use of it.
In many environments the application user is not allowed to read any files outside of the deployment directory. This is mostly done for security purposes - for example if someone hacks your application they won't be able to read a passwords file.
And in professionally managed environments developers often don't have a say in which directory the application will be placed.
So if you need to read a file like properties, images, certificates, etc. you can place it in the application directory (or .war file) and use getRealPath("") to get the path you need to load.
As an alternative you can place the external files on the classpath but there are sometimes issues with this. For large files most app servers will try to load the entire file into memory and cache it if it is on the classpath.
The getRealPath() gives the absolute path (on the file system) leading to a file specified in the parameters of the call. It returns the path in the format specific to the OS.
The getContextPath() on the other hand returns the URI or the relative path to the resource.
As far as I remember, I've used it to save images or other data files, since it allows you to see where your application is deployed at the moment. For example, Eclipse and Tomcat will create a temporary folder that's buried deep somewhere within your Eclipse profile and deploy the app there.
This is a real path in file system.
From javadoc:
The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including the proper path separators. This method returns null if the servlet container cannot translate the virtual path to a real path for any reason (such as when the content is being made available from a .war archive).
I think it is very clear. Why do we need this? Sometimes web applications perform some manipulation in file system. For example read stuff from files, write files etc. This API allows you to access the place where your JSPs and other stuff is really stored.

Java Servlets - Writing to file

I'm using the Netbeans IDE, and I'm currently using a GlassFish server.
What I want to do is write to a file.
I looked at some pages, and the code I have now (that is not working as far as I know) looks like:
File outputFile = new File(getServletContext().getRealPath("/")
+ "TheFile.txt");
FileWriter fout = new FileWriter(outputFile);
fout.write("The Content");
fout.close();
This is my project's structure:
Also where will the file get placed?
Edit:
I forgot to mention there are some other folders below the ones in the picture: Test Packages, Libraries, Test Libraries and Configuration Files. However I don't think the file would get placed there.
Edit (newest):
I found out the file is stored in the /build/web folder, but this is not appearing in Netbeans. Even after I restarted it.
As you've coded, the file will be placed in public web root. That's where getRealPath("/") will point to. To be precise, it's the folder named Web Pages as in your screenshot. As an exercise, do the following to figure the absolute path, so that you can find it by OS disk explorer.
System.out.println(file.getAbsolutePath());
I don't do Netbeans, but likely you need to refresh the folder in your IDE after the write of the file so that it appears in the listing in the IDE. Click the folder and press F5. This is at least true for Eclipse.
That said, this approach is not recommended. This won't work when the servletcontainer isn't configured to expand the WAR on disk. Even when it did, you will lose all new files and changes in existing files when the WAR is been redeployed. It should not be used as a permanent storage. Rather store it on a fixed path outside the webapp or in a database (which is preferred since you seem want to reinvent a CMS).
Note that this is in no way guaranteed to work in all web containers or through restarts and will most likely be overwritten by a redeployment.
If you want to be able to allow your user to update content, you need to store the new content somewhere and have a servlet or a JSP-page or a facelet retrieve the new content from the backing storage and send it to the browser.
See the documentation for getRealPath. It returns you the location on the disk for something specified with a URL.
I'm guessing your file is in the root of your web application on the disk within Glassfish (where the WAR file is extracted). I don't know enough about Glassfish to say where that will be.
Also, note you are using string concatenation to create the file name, so if the getRealPath call doesn't return a String with a "/" on the end, then you might be creating a file in the parent directory of your web app. Perhaps best to use a File object for the parent directory when creating the File object for the actual file. Check out the File API.
I'd recommend creating the file outside of your web app. If you redeploy your WAR file then you might delete your file, which probably isn't what you want.
Being in a servlet makes little difference to the fact that you want to output a file. Just follow the standard file APIs as a starting point. Here's a tutorial.

Categories