I am writing a servlet (specifically with Scalatra). In the servlet I have many links on a table of contents which is included with every page. I want these links to be relative to the application base. If I use links such as "/foo", everything works fine when the servlet is served from the root (localhost:8080/) but if I serve it from Jetty/Tomcat along with other servlets (localhost:8080/servlet) the link points outside of the servlet.
What is a good fix for this problem?
You need to prepend the link URL with a domain-relative path including the context path as obtained by HttpServletRequest#getContextPath(). I don't do Scala, so I can't give a Scala-targeted answer, but here's how you'd do it in JSP so that the picture is sound:
link
When the current context path is /foo, then the above will end up in HTML as
link
Or if you're generating HTML programmatically using Java inside a servlet class (which is actually a poor practice, but that aside):
out.println("link");
An alternative is to set the <base> tag in HTML so that all relative links are relative to it, see also this answer for more detail: Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP
Related
I've had this simple jsp log-in form that used the css style sheet. It was working just fine until I included the web.xml file in my directory. Now the JSP file won't load the css files no matter what. I've tried changing the link address of the css in multiple different ways but with no luck.
I'm pretty positive that the web.xml file is the reason it's not loading because if I remove it, everything works again.
Here's my project structure:
Here's my login.jsp:
here's my web.xml:
Your web.xml includes /* in a security constraint, limiting access to all content of your application to those users with the role users. This means that, instead of serving your CSS file as requested to the browser, tomcat will redirect to the login.jsp as well (which is obviously an incorrect and not very stylish stylesheet)
I am trying to have a error.html error page in my Java WebApp with web.xml entry as below:
<error-page>
<location>/error.html</location>
</error-page>
having a directory listing as:
--App
-- index.html
-- error.html
-- css/
-- ...
-- js/
-- ...
-- img/
-- ...
-- folder/
-- index.html
When I enter an address say:
/App/some-wrong-address or /App/folder/some-wrong-address
In both the cases I am able to see the Error Page called in as part of 404 error, but in latter case I am not getting my resources like caa, js, or img pulled up.
I understand that the resources are called relatively with ./... path and in the second case it is expecting it to be ../... because of directory change, but I want to OVERCOME this thing, I am not directly working on production server and I cannot use exact URL of everything with localhost as it will have to change later everywhere.
Let me know how can I do this?
I am using Tomcat 8.0.28 and WebApp version is 3.1.
The key is to correctly produce all of the HTML that your webapp produces. The HTML must have the correct URLs (note: they are URLs, not paths) in the elements that refer to other assets (CSS, images, javascript).
You are correct that putting the absolute URL of your production system in your source files is not a workable solution.
In a JavaEE web app I worked on, we used JSF Facelets as the templating system for producing our HTML. In that we wrote each URL like this:
<script src="#{request.contextPath}/foo/bar/baz.js" />
<img src="#{request.contextPath}/img/something.png" />
This allows any template, at any location in the URL hierarchy, to reference any asset. The JavaEE app server handles filling in the correct context path so that the resulting URL the browser handles is correct regardless of where it is hosted.
application.getContextPath() will give you page context,and you can base ur urls accordingly after that..will work on local server as well as deplyment server..
e.g: ... href=" <%=application.getContextPath()%>/css/yourcss.css" ... etc.
N.B.: its a good idea to design your error page in a way that it as no dependencies to any other files..styling and resources in that case should be absolute or inline and images if any should reside in the same folder as your error page
It says in the Oracle webapp documentation
If a resource matches a URL pattern in both a servlet-mapping and a
jsp-property-group, the pattern that is most specific applies
(following the same rules as the servlet specification).
Why can't both be applied? Say I don't want a user to go directly to a jsp file, rather have it go through a servlet first, which will then forward that jsp to the user. But I also want that jsp file to have a prelude, coda, etc. Is there a collision here that one of them has to win over the other?
If you don't want the user to hit your JSP, stuff it underneath WEB-INF. The container can see those JSPs, but nothing from outside can.
Then, you'll see, the Servlet will have one URL, while the JSP will have a separate, different URL.
The external URL, the one representing the Servlet, doesn't (necessarily) conflict with the URL for the JSP. You then code up the property group on the JSP file itself.
Your Servlet will do its processing, and then FORWARD to the JSP (it can not REDIRECT, since the JSP is buried in WEB-INF, and the outside world can not see it).
The property group mapping works against the URL of the resource your are FORWARDing to, the JSP.
So, there's no conflict here. Simply two different URLs, one taking the initial request (the Servlet), the other the rendered resource that you FORWARD too.
So here is my story.
I am developing a spring web application. The reloading of static content (js, css, jsp) was broken and found a solution in the following thread:
Getting resources in VFrabric Server to deploy without causing container to reload
In order for reloading to work I couldn't have the root URL '/'. So I change that to '/project' and my reloading works. Great!
But then comes the next problem. I have a lot ajax requests to '/typeahead/searchUniversities/%QUERY' for example, this would need to be changed to 'project/typeahead/searchUniversities/%QUERY'. And when I upload it to the production server I would need to change it back to '/typeahead/searchUniversities/%QUERY'
Since '/project' is just for development
So the I read about profiles but I'm not sure if this is the way to go. I might overdoing it?
I was also thinking of having something like '${baseurl}/typeahead/searchUniversities/%QUERY' and then just change in one place before production. But not sure how to do this.
If someone could guide me with an example of how to do this it would be great.
Thank you!
Edit : add another more direct way to get the context path in a JSP
The url should never be static in the webapp : the context path is determined at deployment time and not at compile time. If you are using spring tag library, you can make use of <spring:url> tag, if not of the JSTL <c:url> tag. Both will automatically add the context path for you.
BTW : in a JSP <%= application.getContextPath() %> gives the context path without any additional taglib.
But please only use relative paths where it has sense and never for "top level" URLs.
Your application shouldn't depend on the context path it is deployed under. One solution to this particular issue would be to use relative paths in your ajax requests,
e.g.
'typeahead/searchUniversities/%QUERY' rather than '/typeahead/searchUniversities/%QUERY'
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.