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.
Related
I've created this project through Spring Boot. It's a full stack web app that takes information from a user, validates it, sanitizes it, authorizes it, and then sends it to a database. It also can retrieve data from a database.
The problem is that, when the project runs, it should open the home page automatically. Instead, I have to navigate to it manually through a browser, resulting in Access Control Allow Origin issues (as it appears that AJAX is being sent cross origin).
My current directory structure is like this:
C:\Users\workspace\Repository\Project\src\main\resources\templates
Within this templates folder, I have my webpages and config folders. These config folders contain the Javascript files.
I've looked at other projects I've created, and directory structure is very different, but they all use jsps. They look like this:
C:\Users\workspace\CapstoneProject\src\main\webapp\jsp
This directory has all the jsps in it, and they start with the project.
What is the appropriate directory structure so that they start with the project? I've googled this and looked on Spring's website but have found nothing.
The location is less important and it depends on your ant/maven/gradle/script of building your artifact for example War file which it should be copied to webapps folder and then folder for resource type as jsp/css/js/html
Static resources as html can be outside your war in a separate resource folder.
According to tomcat it depends on your size of the application:
*.html, *.jsp, etc. - The HTML and JSP pages, along with other files that must be visible to the client browser (such as JavaScript,
stylesheet files, and images) for your application. In larger
applications you may choose to divide these files into a subdirectory
hierarchy, but for smaller apps, it is generally much simpler to
maintain only a single directory for these files.
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 upload an image from hard drive and then store it in some folder in my app.
But the image isn't displayed immediately on my JSP, it is displayed only after I restart the app.
I guess that's because when the app resources are loaded, required image file doesn't exist in the destination folder yet.
So, I think that reloading app resources programmaticaly immediately after storing the image file into the destination folder will solve my problem, but I don't have a clue how to do it.
Update 1:
Part of jsp were the image is asked for:
<img src="${pageContext.servletContext.contextPath}/img/${imageUrl}" />
where imageUrl is the image file name with it's extension.
The images are stored in MyProject/src/main/webapp/img/
Could anyone help me?
Thanks in advance.
I see.. Thanks.
Here is what happens (IMHO :) ) :
During the JSP processing the variable gets resolved to some static path and gets passed to the browser.
Browses renders the static content here, once it sees the path it issues additional http request to the server, but it seems like your server can't find your image statically.
Its due to the fact that you Can't change the war physical structure once it gets deployed.
Think just like you work with a file based representation of WAR and not with exploded directory.
Now what you can do?
Try to create a resource servlet that will get the request to bring the binary image and will return it.
Register this servlet in your web.xml with path like,say, /resource and make it get the get parameter imgName
Example
<img src="resource?imageName=${imageNameYouWant}" />
In your jsp instead of static content in img src tag call the servlet with image as a parameter.
When browser sees this it issues a regular request like before but this time it gets processed by your resource servlet and it will bring the image.
Another thing I would try is just to move the images folder outside the webapp directory.
This directory is tracked by your web container automatically but there is no reason to store the images there as well.
You do like this:
Create a directory like: /myapp/images
You'll still need to create some component on the server side. But this time it can probably be done by creating some configuration on the web server side (no custom servlet).
I'm not sure this will work when you use the first approach...
In JSP point on the server as I've already explained above.
It its an enterprise serious application I would recommend the first approach in conjunction with storing the images in the database but its a different story :)
Hope this helps
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 a web application, which was designed and always worked under root context ("/"). So all css, js and links started with / (for example /css/style.css). Now I need to move this web application to some different context (let's say /app1). It is easy to change server.xml configuration file and bring up web application in new context app1 using [Context path=""] item. But web pages are broken because all links are now incorrect. They point to old root context /css/style.css instead of new app1 context.
Is there any magic way to fix this problem without fixing each link by prefixing with some "context" variable?
Used server - Tomcat 5. Application is written with Java and uses JSP, Struts2, Spring and UrlRewrite filter. More interesting is to hear real experience in fighting with such problems that theoretical debates.
Thank you.
P.S. I do not see how UrlRewrite filter can help me because it will work only in app1 context. So requests to links like /css/style.css will not be passed to it.
If you use URL rewriting to redirect ROOT to your application, won't that eliminate the ability to have a an application in ROOT? If so, what is gained by switching the context?
I think the general way to link resources is to either append a "context" variable and make the link absolute: ${pagecontext.request.contextpath}/css/style.css or just make the link relative: css/style.css
Unless you have specific reasons for being unable to modify the code, I would do a search/replace on the links and be done with it. You should have no more than three or four expressions to find, /css, /images, /javascript, etc.
You should always create urls via url re-writing, not only so that session info can be added to the url, if required, but also so that the context path can be added. You should create all urls as absolutely paths from the top of the application and then let url-rewriting handle adding the context-path to the front, as appropriate.
<c:url value="/css/site.css"/>
That will render /<context-path>/css/site.css or /<context-path>/css/site.css;jsessionid=134345434543 into a jsp file if they don't have cookies enabled. You can also use the c:url tag to render the url into a variable and then use that variable multiple times throughout your document. Just add a var="x" attribute to the tag and then ${x} will render the url into your doc. If you aren't using jsp to render your output, you'll need to find the appropriate mechanism for your view layer, but they will all have one. If you are rendering a url in java code, just take a look at the source code to the c:url tag and you'll see how it is done.
The one awkwardness is that CSS files (and js files) aren't processed, so urls in css and js files need to be relative paths or they will break whenever you change the context path. Most js already uses relative paths since library maintainers don't know what path you are going to install their library to. CSS backround images, on the other hand, are often specified as absolute urls, since the same CSS file may be included into html files at different levels of a file hierarchy. There is no easy fix for this that I am aware of other than to create appropriate symlinks such that the relative url always works or else serve up the problem CSS files via a JSP so that the urls can be rewritten as appropriate. I'm sure there are probably filters or apache modules you can run which will do the url replacement, but then you've still got to manually update your filter/module whenever you deploy to a new context path.