can't access play-scala public folder resources - scala

For my play-scala project, My routes file has:
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
however, I am not able to retrieve any resource from this folder. For example, I placed a png file calleg favicon.png in the public folder, yet, if I run
http://localhost:9000/public/favicon.png
the play server can't find the resource. Any ideas about what to look for to repair this problem?
The server also says that tried the route:
GET/assets/$file<.+>controllers.Assets.versioned(path:String = "/public", file:Asset)
But no luck.

You are reading your configuration wrong, the correct request would look like this:
http://localhost:9000/assets/favicon.png
That way favicon.png will be searched in public folder, not another way around
If you want your original URL to work, you'll need to change your configuration to following:
GET /public/*file controllers.Assets.versioned(path="/public", file: Asset)

Related

Unable to read file from resources nested directory

I am currently including a submodule to my project (a scala project, using Maven for dependency management):
[submodule "src/main/resources/secrets"]
path = src/main/resources/secrets
url = <my repository url>.git
Having this submodule, my resources path (src/main/resources) looks like:
src/main/resources/secrets/anotherdirectory/secret.conf
If I try in my local to read the file using com.typesafe.config.ConfigFactory, it works well:
ConfigFactory.load("secret").getConfig("config")
However, when I run the application (using the .jar), I am unable to do the same, having the following error (and the file is the same):
com.typesafe.config.ConfigException$Missing: no configuration setting found for key
I've also tried to read as a file, which also works in my local, but gives me a null when .jar:
getClass.getClassLoader.getResource("secrets/cloud/anotherdirectory/secret.conf").getFile
Anyone had any similar issue?
Thank you.

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"))
}

playframework2 jquery error (jquery.min.map)

When I launch my minimal play2 application I can see an exception in the js console like:
GET http://localhost:9000/assets/javascripts/jquery.min.map 404 (Not Found)
Why it happens? Is it known issue. I've seen some play-tool-projects on github that has this file there. By default I do not have this file in my "javascripts" folder. Should I?
The source map file maps the minified version of the code against the un-minified version so that you can access the real code while debugging.
The 404 error only appears when using the developer tools. To fix this, just download the correct version of your source map file. Mine for example was:
jquery-1.9.0.min.map
Then rename it to:
jquery.min.map
and move it in the javascripts directory.
Try to map of the Assets controller in your conf/routes file.
GET /assets/javascripts/jquery.min.map
For more information read this documentation
Working with public assets

Servlet cannot find the file I'm trying to open

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.

Specifying location of .csdl / .ssdl / .msl Metadata files within the output assembly

I have an EF project that containing my data model that I have been successfully using. The "Metadata Artifact Processing" option is set to "Embed in Output Assembly".
As the .edmx file was in the root folder of the project the metadata string used in the EntityConnectionStringBuilder was set to:
res://*/myProject.csdl|res://*/myProject.ssdl|res://*/myProject.msl
When I was restructuring the project, I moved the .ecdm file into a subfolder:
/DataLayer/myProject/ and I changed the metadata string to:
res://*/DataLayer/myProject/myProject.csdl|res://*/DataLayer/myProject/myProject.ssdl|res://*/DataLayer/myProject/myProject.msl
This now causes an error ("The specified metadata path is not valid") but I can't see what's wrong with the folder path I've specified in the metadata.
I know that I can just move the .ecdm file back to the root but I've had this problem before and couldn't fix it - is there something obvious I'm missing?
I finally worked it out.
The folders should be separated with '.' not '/'.
The correct format for the metadata is:
res://*/DataLayer.myProject.myProject.csdl|res://*/DataLayer.myProject.myProject.ssdl|res://*/DataLayer.myProject.myProject.msl
Hopefully this will save someone from banging their head against the wall for a while!