I encourtered several problems when I try to distribute jar/jnlp dynamically. All my files are dynamically served using http://www.mywebsite.com/ServeFile?name=xxx for file xxx. I can download files correctly.
When I put the link to jnlp in the browser and download, there is an error from javaws showing that the jar file was not found. The GAE log file shows that the javaws tried to load /ServeFile.pack.gz?name=test__V1.0.jar so it wasn't served by the ServeFile servlet, instead it was served by / (which is another servlet)
Here is my jnlp file partial content:
<resources>
<j2se version="1.6+"/>
<jar href="ServeFile?name=test.jar" main="true" version="1.0"/>
<property name="jnlp.packEnabled" value="true"/>
<property name="jnlp.versionEnabled" value="true"/>
</resources>
My question is how does the javaws put .pack.gz into the middle of the url, instead of just putting a AcceptEncoding in the request? What is the right way to serve jnlp and jar dynamically?
Update
Problem solved when using a "static" type link such as http://website.com/path/file.jar without using ?file=file.jar. I still have a problem:
New Problem
JavaWS will sometimes put ?version-id=1.0 and my dynamic url is also using similar pattern like ?folder=root&user= guest. So version-id would become 1.0?folder=root.
If I put &folder=root&user=guest it would work, but javaws sometimes request myjar__V1.0.jar& folder=root so now the file name has myjar_ V1.0& folder=root which is wrong. It's not consistent.
Temporarily, I can just parse this version-id to see whether it contains a question mark. I hope there is a better solution.
On GAE, consider putting the files in the blobstore and using the blobstore service to serve them up.
The Blobstore can serve any binary file
https://developers.google.com/appengine/docs/java/blobstore/overview
I got a temporary solution but yet another problem. This jar is stored in datastore, so I need http://www.myserver.com/?file=start.jar to access it. Once I use http://www.myserver.com/start.jar it then works. I just need my servlet to parse the Path instead of getParameter which is still easy.
Problem is with pack.gz and version-id. If you link is http://www.myserver.com/start.jar?folder=root&user=guest then javaws would generate http://www.myserver.com/start.jar.pack.gz?version-id=1.0?folder=root&user=guest for which your getParameter("version-id") is 1.0?folder=root so you possibly think you could use &folder=root&user=guest
But your link could also become http://www.myserver.com/start__V1.0.jar.pack.gz?folder=root&user=guest (which is good). I don't think you can guarantee which one javaws uses so you can't prepare to use ?folder=root or use &folder=root.
Related
Been trying to score 100/100 on Google's page insights tool, but no matter what i try it won't recognize the .htaccess file (to leverage browser caching for images/font files). The file is currently in the root directory and just copied the .htaccess file from this boilerplate.
This question here has an answer which states:
.htaccess is not directly supported and instead it uses the app.yaml
file to accomplish much of what .htaccess provides.
So how exactly do we go about leveraging browser caching in a java based maven project? (which doesn't use app.yaml)
I can't find any documentation about it...
You can configure a cache duration for specific static file handlers in the appengine-web.xml file, as explained here. For example:
<static-files>
<include path="/**.png" expiration="4d 5h" />
</static-files>
Or you handler can set cache durations by returning the appropriate Cache-Control and Expires HTTP headers to the browser.
i'm trying to get the absolute path of my eclipse project :
so i write this;
File file= new File("");
System.out.println(file.getCanonicalPath());
projectPath=file.getCanonicalPath();
so it gives me the right path when i execute it in a class as java application C:\Documents and Settings\Administrateur\Bureau\ready code\JavaServerFacesProject
But when i try to use it in my web application it gives this :
C:\Documents and Settings\Administrateur\Bureau\eclipse\eclipse
So any idea how to do it
Many thanks
Reading a file from a web application is a classical pitfall, whenever you do this you will suffer.
Web apps (especially Java EE) are not thought out to use the file-system for read/write operation, they rely on the fact that the container (in your case Tomcat) knows how to get the needed resources.
So the basic advice is : don't do it.
But since I basically hate this kind of answers I will give you some advice.
Never use the working directory
You never know where your working directory is, and, more often then not, in any production system, the web-app has no right to write on the working directory.
For example, if you deploy your webapp to a tomcat server, run as a service on a windows machine, you'll find that your working directory is \Windows\System32
You really don't want to write some uploaded files there for example...
You have a few option, what I prefer is to set a path into the web-xml and possibly override it from server configuration (using context).
Second option, even better is, to save a path into a db-table accessed by the web app.
ex:
in the web.xml you set
<context-param>
<description>Uploaded files directory</description>
<param-name>file-storage</param-name>
<param-value>c:\app\storage\uploaded</param-value>
</context-param>
Then in the you server.xml (or you could use the context dir and place there a file with the following code) you override this setting in context.
<Context
<Parameter
name="file-storage"
value="E:\app\storage\uploaded"
type="java.lang.String"
override="false" />
</Context>
Check tomcat documentation
Third option, in the slightly happier situation, you want to write just some temporary file, there is the webapp working dir accessible as a servlet context param named :
javax.servlet.context.tempdir
If I where you I would go for the database table.
All this complexity is because you can have multiple instance of the same app on different instances of tomcat, even on different machines, and even different web application into the same instance, so there is no easy way to make a 'relative' path is all situations.
Most web-app resolve to serialize data on db (using lobs or similar objects), whenever there is such necessity, or to rely on some kind of service (FTP, cifs, nfs ...).
In Eclipse, you can set a Working Directory for your project in the Run Configurations dialog.
Have you tried setting a non-default one there?
(If you cannot set anything, you could try the JVM option suggested here: https://stackoverflow.com/a/7838900/1143126 )
I have a standalone simple java web application with servlets and jsp, say the name is FileDisplay I am access its home page through url - http://localhost:8080/FileDisplay/index.jsp.
What the application essentially does is, retrieves a list of file names(.xml's and .pdf's) with complete path. These files are stored in various external directories, say D:\ABCD, D:\XYZ, D:\PP\2012\08 etc but on the same machine as the web application just on a different drive. So the return list is something like-
D:\ABCD\filename1.xml
D:\ABCD\filename2.xml
D:\ABCD\pdf1.pdf
If I use a simple <a href=""> in the jsp then it doesnt work. in the viewsource it looks like -
file1
I think it is beacause these files are not part of the webapp, so the container doesnt think it is local and hence unable to open them. When I place the mouse pointer over the link, the status bar shows as file:///D:\ABCD\pdf1.pdf. I also tried prefixing file:/// in the href, even then it doesnt work. So I tried a few other things.
One thing I tried is setting the Context in Tomcat's server.xml but even that doesn't seem to work. I am using eclipse to build and deploy and run the tomcat, so the server.xml I modified for this context is one within the eclipse workspace.
The setting I used is -
<Context docBase="D:/ABCD" path="/File-Display/NB" reloadable="true"/>
I have another context set for the main application which is -
<Context docBase="FileDisplay" path="/FileDisplay" reloadable="true" source="org.eclipse.jst.j2ee.server:FileDisplay"/>
What am I doing wrong here?
Does it explain a bit more now?
I think you are on the wrong way.
If you want to provide access to different files distributed in your file system create controller (servlet) that accepts URL, reads appropriate file and writes it to the response output stream.
This way you can control access to your resources, make them secure, etc. You will be able to modify your application easily (e.g. if you change the files location). Etc, etc.
I have a Java webapp running on Tomcat.
At runtime, I create images files that I want to be publicly published on the tomcat server.
1/ How can I get the local URL where I want to copy my image files? (ie /mylocalpath/to/where/i/should/store/the/file/)
2/ How can I know the URL where other machines can access this public files? (ie http://mydomainname/myapp/myresource.png)
Keep the path in a servlet init-param, a JNDI string, or in a property file. (Or whatever is provided by your framework that allows simple configuration.)
Create a servlet/action/controller/etc. that's mapped to a known URL. Either pass in a param with the filename or make the filename part of the URL. Stream the contents of the file back to the user. (Search for "image servlet" for examples.)
Bear in mind the mime type of the file and set the appropriate header. If necessary, check if the requesting user has access to the file in question. (There are several ways to implement that.)
I've figured a much simpler way to do this (which may sound obvious to Tomcat experts but useful to others).
In Tomcat 6 "server.xml" file, I've added this line in the <Host> element :
<Context docBase="/mylocalpath/to/where/i/should/store/the/file" path="/uploads" />
Then, when i create my resource i copy it in this local directory and figure out the public URL pretty easily : http://myserver/uploads/myfilename
Hope it can help other people.
(I even think the context can be defined in a context.xml included in the WAR rather than in Tomcat's global configuration but a global definition was enough for my needs).
I have been searching on this but the info I am finding seems overly complex for what I am trying to do or involves having to specify exactly what type of file is being downloaded and use a specific Java class for that, I'm wondering if there is a way to not have to do this and to be able to use one way of doing this regardless of the file type as I am not generating the file, just taking it from where it exists in my directory. I have a set of files in a folder locally, say:
/media/files/files
and in this directory I have a variety of different files, .jpg, .doc. .xls, .png, etc and want the simplest way that I can take a given file path, retrieve it from the directory and send it back to a JSP so that it will enable the user to download the file. The info I am finding always seems to involve de-serializing from a blob, pulling from a remote location, or something like this to where the code is rather lengthy and I figure there must be a fairly simple way to do what I am trying to do given that I have the files locally and they are in regular format (not in a DB, etc)
Any advice is appreciated
EDIT Thanks to Costi I think I am on the right path now but I tried this, below, and am still not able to access the file:
I have put this in my server.xml file in my tomcat /conf:
<Context path="/files" docBase="/media/files/" />
and then tried accessing a file at http://myip:8080/files/test.txt but it is not working, in my Spring web.xml the only Servlet-mapping I have is:
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/d2/*</url-pattern>
</servlet-mapping>
Any advice is greatly appreciated
FIXED: Forgot that the server.xml in Eclipse overrides the server.xml in the tomcat server which was the issue as to why it wasn't working
If you do not want any logic wrapped around the download, you can simply make the files available as static resources, provided that the authentication/authorisation stuff is handled by the container if needed. For this to work, you simply need to map Spring DispatcherServlet so that it won't handle requests to /media/files/, one simple way to achieve this would be to have the spring servlet mapped to some extension like /.html, or have mapped to a subdirectory instead of /. This way, the container will handle requests to your /media/ stuff and it will simply serve static files.
If you need to interfere with the download somehow (for instance, if you handle auth stuff outside the container or you want to take some action prior to or after every download), then you can have a View returned from your spring controller that simply proxies the requested file to the output stream, after setting the proper headers like Content-Type, length, disposition and so on. I don't know of any such built-in view, but it's pretty easy to create one yourself and perhaps write your own ViewResolver that will return an instance of that view for file names under /media/whatever.
I hope this helps.