How to prepend front controller servlet mapping to urls in jsp - java

I have a simple java web application running in Tomcat.
In it, FrontController.java servlet has mapping #WebServlet("/controller/*"). So, in order to fire the servlet, I need my every url to start with /controller/. I need to be able to display images on pages images are stored outside container, so that I write them to OutputStream). But if I write my src urls like ${pageContext.request.contextPath}images/picture.jpg then the resulting url will be obviously localhost:8080/rootFolder/images/picture.jpg and not the localhost:8080/rootFolder/controller/images/picture.jpg.
To load these files I can either manually prepend controller/ after every ${pageContext.request.contextPath} which is bad or I can follow the advice found here append dispathcer servlet mapping to url and add line request.setAttribute("frontControllerMapping", "controller/"); to every method which processes request and then code urls like this ${pageContext.request.contextPath}${frontControllerMapping}images/picture.jpg which is better.
My questions are how to prepend the controller mapping to every url which must be processed by servlet and how to do it right? Is the second option the correct way to do so?

Instead of adding the complete URL for each resource you can use relative URLs. If that is not an option, than you could simply map all requests to your servlet like this:
#WebServlet("/*")
Then you don't need to worry about adding the controller path to all URLs.

Related

javax.servlet.ServletException: AS-WEB-CORE-00089 exception In servlets

I have a servlet called Document to which I want to redirect all requests starting with Document something like
http://localhost:8080/CollabEdit/Document/abcdwcklsclds
should be redirected to servlet Document.
So, I used an annotation like this :
#WebServlet("/Document/*")
However, for some unidentified reason, it gives an exception that says:
javax.servlet.ServletException: AS-WEB-CORE-00089
This exception is in Document.java is thrown as soon as I call
request.getRequestDispatched("main.html").forward(request, response) .
otherwise no exception.
however, With same request in other servlets, main.html gets called just fine.
A forward and a redirect are not the same thing. A redirect allows you to go to any URL, eventually on another server or with another protocol, because you ask the client to query that URL.
In a forward you ask the servlet container to pass the control to another servlet of the same application (inside same context). As you use a relative path you are actually requesting what is the servlet for : http://host.do.main/appname/Document/main.html because the relative URL is added at the end of the address of current page (it could even be .../Document/.../main.html) !
And you declared that any page under /Document should be served by the Document servlet ... so the infinite loop ...
You can fix it two ways :
if you really need to use relative paths (it is inherently dangerous but you might have reasons to do it), try ../main.html if called from /Document or ../../main.html if called from /Document/something
use an absolute path :
contextPath = request.getContextPath();
request.getRequestDispatcher(contextPath + "/main.html").forward(request, response)
The Filter looks right.
Are you using Servlets 3.0 and no older version? In older versions you would have to edit the web.xml. And in 3.0 it would have to look like in this Post
Does Document extend HttpServlet?
Could you show us some more of your Code, maybe then it would be easier to see what's going wrong.
Greetings

How to make more specific urlPattern override broader pattern with annotations

I currently have a main controller servlet with the following annotation:
#WebServlet(name="ControllerServlet", urlPatterns={"/", "/home"})
I have .js and .css files under the /resources dir in my project that my .jsp files reference and the links are getting sent to my main controller which I don't want. I made a second servlet to handle the .js .css files with nn annotation of:
#WevServlet(name="ResourceServlet", urlPatterns={"/resources"})
hoping that it would pick up the requests coming from my .jsp files but ControllerServlet is still picking them up. How can I make /resources urls get directed to my ResourceServlet?
The url pattern / matches anything that isn't matched by the other mappings. If you have
#WebServlet(name="ResourceServlet", urlPatterns={"/resources"})
then a request to, eg. localhost:8080/context/resources will be handled by your ResourceServlet, but a request to localhost:8080/context/resources/somescript.js won't because it doesn't match ResourceServlet's url pattern. Therefore, ControllerServlet will handle it.
You need to change your ResourceServlet mapping to
#WebServlet(name="ResourceServlet", urlPatterns={"/resources/*"})

Is it possible for a Servlet filter to retrieve its url path?

I can map a single servlet to various url patterns in the web.xml file. When programming the servlet, I can then get which of those url patterns the request is matching, by getting the servlet path through request.getServletPath().
How can I achieve this with filters? When mapping a filter to various url patterns, is there a way to get what path the current request is matching?
Because my filter is currently working on content that is mapped to the DefaultServlet, the request.getServletPath() returns the whole path, and PathInfo is always null.
I am a newbie on servlet and filters, so I hope my question is clear and makes sense at all.
No, there isn't. You have to determine it yourself based on the request URI and a predefinied set/list/map of all known/supported paths. You can if necessary set those paths as <init-param> of the filter and process it during the init() method so that you can reuse it in the doFilter() method.

Make all requests to mysite.com/user/specified/path run the same JSP

I want to allow users to create groups in my application and access them via URL. For example, if you made a group called "sweethatclub," you could access it at http://mysite.com/sweethatclub. Of course, the same code will run for /sweethatclub and /drillteam and even /students/yearbook
I'm running in a Java servlet environment, and can't quite get the paths to align for this. I can write a filter that intercepts all requests and adds information to the request by parsing the URL, but then I want to run the code of an index.jsp. I don't want to map index.jsp to all URLs, because, for example, /images/smiley.jpg still needs to respond the with appropriate file instead of index.jsp.
Is there a way to send all requests to a servlet, unless the request is matched by a plain-old file? Or, is there some other way to accomplish what I want here?
Please let me know if I need to supply more information. I'm new to this environment.
The URL patterns in the web.xml are not supposed to be smart enough to figure out target URL's nature. If you can tolerate it, the easiest way would be to place all the user specified paths under a a well known root... someplace separate from the static files. So you end up with user specified paths like http://mysite.com/sites/sweethatclub.
Alternatively, you can move all your static content under http://mysite.com/static/, and set up the servlet mappings or filters to treat anything starting with 'static' different from the dynamic URL space.
If you are in a Unix invironment, you could just create all the "group sites" as virtual directories that just point to your default one.
Map the servlet on a specific URL pattern
<url-pattern>/groups/*</url-pattern>
Put all static content in a common folder, e.g. /static and fix all URLs in the pages to point to that URL instead.
Create a filter which is mapped on
<url-pattern>/*</url-pattern>
and does the following job in doFilter() method
String uri = ((HttpServletRequest) request).getRequestURI();
if (uri.startsWith("/static/")) {
chain.doFilter(request, response); // Goes to default servlet.
} else {
request.getRequestDispatcher("/groups" + uri).forward(request, response);
}
No, this does not end up with /groups in browser address bar URL. It's fully transparent. You can if necessary make "/static" and/or "/groups" an <init-param> of the filter so that it's externally configureable.

Modify the filter chain - Or select servlet to respond to request using filter

I am trying to use a filter to map requests. I am trying to do this for two reasons, firstly to dynamically generate URI's and have them mapped to the appropriate servlet and secondly to catch URI's which are not registered and handle them appropriately.
So I'm using a catch-all filter to process the URI and determine the response. I would like some way of modifying the filter chain, or some way to set the servlet which responds to the request from within the filter. I have been unsuccessful using filterConfig.getServletContext().getRequestDispatcher().forward() to send to jsp, ideally though I would like to map to a servlet but can't figure out how.
The reason I am not doing this from within a servlet is that I have some URIs which are fixed within web.xml and if I use a catch-all servlet those URIs do not get mapped. Is this possible, is it clean or it going to get really messy?
I don't think this is the right way to do it.
If you look at what web MVC frameworks do, they have a front controller servlet that maps URLs to controllers, which themselves can accept HTTP requests and return HTTP responses. I think that's a design worth emulating, not your filter idea.

Categories

Resources