Servlet cannot find the file I'm trying to open - eclipse

I read that the servlets map the current location based on the url. Clicking a button from my Home.jsp page directs me to my servlet, ExcelUploader. The URL when said button is clicked is
http://localhost:8080/ServletExample/ExcelUploader
I'm trying to open an excel file located in the same folder as my JSP. so that means I have to move one folder up relative to the url above. I have this in my servlet:
InputStream inp = new FileInputStream("../OpenMe.xls");
However I'm still getting a
java.io.FileNotFoundException: ..\OpenMe.xls (The system cannot find the file specified)
This is how my project is setup:

The FileInputStream operates on the local disk file system relative to the working directory and knows absolutely nothing about the fact that it's invoked from a Java EE web application. Any relative path you pass to it is relative to the folder which was been opened at the moment the command to start the server is executed. This is often the server's own installation folder, but in case of an IDE this can also be project's own root folder. This variable is not controllable from inside your Java code. You should not be relying on that.
You've stored the file as a resource of the public webcontent. So it's available as a webcontent resource by ServletContext#getResourceAsStream() which returns an InputStream. If you have absolutely a legitimate reason to invoke the servlet by its URL instead of just using the file's own URL http://localhost:8080/ServletExample/OpenMe.xls, then you should be getting at as follows:
InputStream input = getServletContext().getResourceAsStream("/OpenMe.xls");
// ...
If your intent is indeed to restrict the file's access to by the servlet only, you might want to consider to move the file into the /WEB-INF folder, so that the enduser can never open it directly by entering the file's own URL. You only need to change the resource path accordingly.
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/OpenMe.xls");
// ...
You should not be using getRealPath() as suggested by the other answer. This won't work when the servletcontainer is configured to expand the WAR file into memory instead of into local disk file system, which is often the case in 3rd party hosts. It would return null then.
See also:
getResourceAsStream() vs FileInputStream

Paths for files that live in the webtree have to be "translated" using getRealPath before they are usable, like this:
File excelFile = new File(getServletContext().getRealPath("/OpenMe.xls"));
While you're at it, using the default package isn't a good idea, create a package for your files.

Related

How to import remote python files using pyscript

Pyscript allows one to run python inside a web browser. I have two python scripts I wrote that I’d like to use. One way to do this is to copy and paste the python code held in these files directly into the index.html file where the index file is part of a GitHub.io page. If possible however, I would rather load/Import them from a remote location. Currently, they reside in the gh-page branch on GitHub alongside the index.html file.
My question is whether this is possible? Most tutorials show how to load and import a local python file which I don’t want to do.
Update: This is my current attempt which I add to the index.html file:
<py-config>
[[fetch]]
from = "https://github.com/etc/blob/gh-pages/"
files = ["myadd.py"]
</py-config>
When I try this I get the error message:
(PY0001): PyScript: Access to local files (using "Paths:" in ) is not available when directly opening a HTML file; you must use a webserver to serve the additional files. See this reference on starting a simple webserver with Python.
I want to avoid starting a server because this is meant to be client-side only approach with only a dumb file repo at the other end.
There is a solution, and it's very simple, just use the syntax:
<py-script src="mypythonscript.py"> </py-script>
And it will pick up the file from the GitHub directory.

scala issue with reading file from resources directory

I wrote something like this to read file from resource directory:
val filePath = MyClass.getClass.getResource("/myFile.csv")
val file = filePath.getFile
println(file)
CSVReader.open(file)
and the result I got was something like this:
file:/path/to/project/my_module/src/main/resources/my_module-assembly-0.1.jar!/myFile.csv
Exception in thread "main" java.io.FileNotFoundException: file:/path/to/project/my_module/src/main/resources/my_module-assembly-0.1.jar!/myFile.csv (No such file or directory)
Whereas, if I run the same code in IDE(Intellij), no issues and the path printed to console is:
/path/to/project/my_module/target/scala-2.11/classes/myFile.csv
FYI, its a multi build project with a couple of modules and I build the jars using sbt assembly
This is more related to Java or the JVM itself than to Scala or SBT.
There is a difference when running your application from the IDE vs the command line (or outside the IDE). The method getClass.getResource(...) attempts to find the resource URL in the current classpath, and that's the key difference.
If you look at the URL itself, you will find that in the first case you have a my_module-assembly-0.1.jar! bit in it, meaning that URL is actually pointing towards the contents of the JAR, not to a file accessible from the file system.
From inside your IDE your class path will include the actual files on disk, from the source folders, because the IDE assumes that there is not any JAR file itself. So when obtaining the URL given by getClass.getResource(...) you have an URL that does not have the my_module-assembly-0.1.jar! bit in it.
Since you want to read the contents of the file, you may want to do a getClass.getResourceAsStream(...). That will give you an InputStream that you can use to read the contents regardless you are in the IDE or anywhere else.
Your CSVReader class may have a method that allows it read the data from an InputStream or a Reader or something similar.
EDIT: As pointed out by Luis Miguel Mejia Suarez, a more Scala idiomatic way of reading files from your class path is using the Source.fromResource method. This will return a BufferedSource that then can be used to read the file contents.

play framework reading file from conf folder with routing

I have a web application with play framework. All images used in the application are kept in public folder and are accessed with the help of a routing defined in the conf/route file. So all the images I used are present in a jar file after build. But my requirement is that the admin will be placing few images that the UI should be able to access. For obvious reasons I can ask them to add images into the jar.
My plan is to ask the admin to add images to a folder inside the conf folder and read it from there using routing (I believe its possible because currently there is a routing defined that's reading a json from the config file).
# Home page
GET / controllers.Application.index
GET /clientConfig controllers.Application.clientConfiguration
GET /testImg controllers.Application.testImg
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
Being totally new to Play framework I can't figure out a way to define routes for that and read images from a folder inside the conf folder . Any help is highly appreciated.
conf folder is a configuration folder so it's not a good idea to expose it as a public folder. For example from security perspective the application.conf or the database migration files contain sensitive data that shouldn't be accessible on any api endpoint.
What you could do is add an additional root folder to the public managed resources for example create a folder called publicImages in the root folder and add the following line to build.sbt
unmanagedResourceDirectories in Assets += baseDirectory.value / "publicImages"
Also remember that adding images to a folder on the deployed server means you won't be able to cluster, i.e. add additional nodes if/when load grows. So your best option is to use some 3rd party storage service, e.g. amazon s3 (it's pretty simple for the admin to upload images to a folder on s3)
If however you insist on adding the images to conf folder, what you could do is create a standard controller that accepts file name in its parameters (path) and stream the content of that file from the conf folder using
Play.getFile('conf/{myfile}') just make sure to enforce some security constraints like verifying no path is provided so malicious user can't traverse the machine's file system. And support only predefined 'safe' file types like images.
As LiorH said, it's usually not a good idea to expose conf folder to public. But if this is really what you want, then you can try to implement your own controller.
In your route file:
GET /configuration ConfController.loadConf(path)
In ConfController:
def loadConf(path: String) = Action {
Ok.sendFile(Play.getFile("conf$path"))
}

Files on my WebDAV mapped drive output rendered files in IDEs instead of actual content

On my mac I mounted a shared drive using WebDAV by going to "Finder > Go > Connect to server".
Now, when I try to view the files using TextWranger or TextEdit I can see the PHP code that I want to edit.
However, if I try to use an IDE like NetBeans/Eclipse/TextMate and create a new project with my shared drive as the "Existing sources" folder I cannot see the PHP code.
Instead I see the HTML output of the files as if I were seeing them through a web browser. Also, if I try to view a file that isn't normally accessibility (a command line script) I see the output as if it were called from the command line.
But a weird thing is if I use TextMate to edit a single file from the shared drive I can see the php code I am trying to edit. It just doesn't work as a project.
Any suggestions or solutions on how I can use an IDE to edit files over WebDAV? And why do my IDEs display the content rendered, instead of the actual file on the file system.
I'm not a specialist at all but I seem to remember that WebDAV clients do send GET requests.
If I'm correct your server may not be able to discriminate between HTTP GET and WebDAV GET thus rendering your .php files. Why this would work that way when working with a project and another way while working with individual files is not clear, though.
Do you get rendered files when you add files to your project manually as well?

Why CGI.pm upload old revision of a file on successful new file upload?

I am using CGI.pm version 3.10 for file upload using Perl. I have a Perl script which uploads the file and one of my application keeps track of different revisions of the uploaded document with check-in check-out facility.
Re-creational steps:
I have done a checkout(download a file) using my application (which is web based uses apache).
Logout from current user session.
Login again with same credentials and then check-in (upload) a new file.
Output:
Upload successful
Perl upload script shows the correct uploaded data
New revision of the file created
Output is correct and expected except the one case which is the issue
Issue:
The content of the newly uploaded file are same as the content of the last uploaded revision in DB.
I am using a temp folder for copying the new content and if I print the new content in upload script then it comes correct. I have no limit on CGI upload size. It seems somewhere in CGI environment it fails might be the version i am using. I am not using taint mode.
Can anybody helps me to understand what might be the possible reason?
Sounds like you're getting the old file name stuck in the file upload field. Not sure if that can happen for filefield but this is a feature for other field types.
Try adding the -nosticky pragma, eg, use CGI qw(-nosticky :all);. Another pragma to try is -private_tempfiles, which should prevent the user from "eavesdropping" even on their own uploads.
Of course, it could be that you need to localize (my) some variable or add -force to the filefield.
I found the issue. The reason was destination path of the copied file was not correct, this was because my application one of event maps the path of copied file to different directory and this path is storing in user session. This happens only when I run the event just before staring upload script. This was the reason that it was hard to catch. As upload script is designed to pick the new copied file from same path so it always end up uploading the same file in DB with another revision. The new copied file lying in new path.
Solved by mapping correct path before upload.
Thanks