Web application URL access java - java

I am trying to understand how the requests works. Unfortunately I was thrown at coding first and only then at understanding.
I wrote some really basic webapplication in java few years ago and it did work as expected. On its main web-page(.jsp) I had following as one of the menu buttons:
<p>test</p>
I am currently writing new webapp and forgot a lot. This time I am doing it with Spring MVC and properly. I can't really understand why this snippet no longer brings me to the home.jsp in current webapplication and why at first I did use it in old app.
Apache gives: The requested resource () is not available.
It is not that I need that sort of direct interaction, it is just I am trying to understand whether resources are accessible via URL? Does Spring MVC brings me extra security, where only servlet handled requests can result in a view? Am I missing something really trivial?
Moreover in that same old web app menu I had direct link to the servlet, but currently I can't make such direct reference to the servlet in the new webapp. I can make relevant request which will be captured by the servlet, but not by the name of it.
Apache gives: The requested resource () is not available.
Reference to servlet from menu:
<% if((String) session.getAttribute("passengerFound") != null){ %>
<img style="border:0" src="menuButtons/My Trips.png" alt="My Trips"/> <%} %>
Thanks, I bet it is really simple. I really want to understand, please help.
I know that it has something to do with Front Controller(dispatcherServlet), but I can't form logical and firm explanation in my head.

it is just I am trying to understand whether resources are accessible
via URL
In short, no. The default behavior and recommended configuration when using Spring MVC is to map the Spring DispatcherServlet to the / url pattern, meaning ALL requests are sent to the DispatcherServlet. Out of the box, the dispatcher-servlet will NOT service any requests for static resources. If this is desired, the two main options are
Map the DispatcherServlet to another pattern than root, effectivly isolating the Spring MVC portion to a sub-context
Add a resource-mapping to your spring context (your applicationContext.xml).
<mvc:resources mapping="/res/**" location="/res/" />
This above would tell spring mvc to treat all request to /res/** as requests for static resources (like images etc) and that those resources are physically located in the /res/ folder in the application root.

You might just be missing a "/" as in "/home.jsp" instead of "home.jsp"

Related

Spring equivalent of tilde (~) for routing from ASP.NET?

Sorry in advance if this is something trivial
In ASP.NET I remember you could direct your routes to
Login
and you didn't have to worry about anything URL related (if your project is on localhost:1234 or localhost:1234/myproject/ or whatever), ASP.NET would do the job for you.
Is there an equivalent for that in Spring. Currently when I start up my project, using GlassFish, it starts up at url localhost:8080/myproject and the resources (css, js...) aren't even being loaded until I add another / in the end (localhost:8080/myproject/).
All my routes are on the first URL parameter and my GET variables aren't even RESTful, simply because if I go one / more, my routing is going to go wrong, ie.
Home //will go to localhost:8080/home (not the project scope)
Home //is fine until I go to another / in url...
//...(/foo/bar), then it goes all the way up
//to localhost:8080/foo/home
I tried to google this, but every time I try to google something equivalent to ASP.NET, I just get a lot of ASP.NET tutorials (nothing Spring related).
So.. is there any way to keep the url consistent, something in the lines of:
Login
or
Login
How is it normally done in (commercial) applications? What's the best practice in this?
You need to use the Spring Tag library.
First import the tag library in your JSP:
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
Now, instead of writing a raw URL, you use <spring:url>, for example:
Login
Or you can assign the value to a variable and reference it:
<spring:url value="user/login" var="login"/>
Login
Which you prefer is a matter of preference.
The tag will then work out the web application context, etc, and replace <spring:url ... with the full URL.

Different URL for development and production. (Reloading static content)

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'

What will tomcat do after I type the root link of a spring application?

Let's say I have an application written with spring framework, and I want to know, when I typed in :
http://localhost:8080/test
link, what tomcat will do to generate response for this request ?
Should it have to pass all filters first, then ????
And after I typed in the url, it always be directed to another link like http://localhost:8080/test/login, where was this redirection implemented ?
If it is hard to explain to me, then please recommend me a book for that, thanks very much !
what tomcat will do to generate response for this request ?
Tomcat will typically send the the request to the relevant DispatcherServlet instance, as configured in your "web.xml" file. This is described in the Spring documentation.
Should it have to pass all filters first, then ????
Yes. Filters are applied before (and after) requests are passed to the Servlet.
And after I typed in the url, it always be directed to another link like http://localhost:8080/test/login, where was this redirection implemented ?
That depends on how you have implemented security. It could be done at the Tomcat level (I think), using SpringSecurity, or hard-wired logic in your Spring MVC controller, or in a plain (non-Spring) Servlet, Filter or (Tomcat specific) Valve.
If you are looking for advice on the best way to implement login / security, I'd recommend using SpringSecurity. SpringSecurity works using Filters.
If it is hard to explain to me, then please recommend me a book for that, thanks very much !
The online Spring and SpringSecurity documentation is as good a place as any. This documentation tends not to spell out exactly how requests get processed in the context of a particular web container, but you should be able to figure the details from the Tomcat docs and the Servlet specification.
If there's a controller that's mapped to that URL, the Spring DispatcherServlet will send the request to it for handling.
If the controller determines that the next view ought to be the one that corresponds to /test/login, then it'll specify so when it sets the ModelAndView.

Changing Tomcat web application context

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.

Spring MVC REST : static files unaccessible because of url-pattern

My Spring Dispatcher servlet url-pattern is /* (as spring MVC REST suggests)
Now all the request are resolved by this Servlet. even CSS/JS/Images also get resolved and handled by servlet..
So, Spring MVC tries to find controller.. :(
How to bypass this? Is there any standard way out of this problem??
& Don't want to change url-pattern to /rest/* (so, other static resources get accessed by /css/ or /js etc.)
You can map your controllers to a smaller set of URLS (i.e. /app/*), and then rewrite the URLs that your users actually see so that they don't even know about. Have a look at the mvc-basic webapp sample, particularly web.xml and urlrewrite.xml to see how this is done.
Map the Spring dispatcher to some subsection of the URL space, and use Tuckey to rewrite URLs the user deals with.
http://www.example.org/app/controller/action -> http://www.example.org/controller/action
Just a heads-up update on this: the default rewrite configuration as defined in the Spring sample did not work out of the box for me. The rewrite rules for stylesheets, scripts, etc. were still processed to the /app/* rule, and subsequently handled by the DispatchServlet, which is not desirable.
I had to add the last="true" attribute to the styles/scripts/images rules to indicate that other rules should not apply, and I had to use the FreeMarker Spring URL macro in any CSS/JS include paths.
Just in case someone encounters the same problem.

Categories