Reusing RequestDispatcher object - java

Inside doGet()/doPost() in a servlet I have:
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/pages/view.jsp");
dispatcher.forward(request, response);
As the path to the jsp is not relative to current request and the RequestDispatcher is obtained from servlet context, can I reuse the same dispatcher object in multiple requests
such that
RequestDispatcher dispatcher becomes instance variable
init() has
dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/pages/view.jsp");
and doGet()/doPost() just have
dispatcher.forward(request, response);
The reason behind doing so is to save the cost of construction(/lookup) of RequestDispatcher for every request. This may really not be significant if the server implementation already caches the objects and looks up dispatcher by the url for every getRequestDispatcher() call, but by obtaining the reference to dispatcher in the code in init, we can save the cost of lookup as well.
Also want to know if will this be thread safe as same dispatcher object will be used every time?

It's supposed to be threadsafe, but there are certain servletcontainer makes/versions where this is not threadsafe. In Apache Tomcat for example, it was not been threadsafe until they fixed it in version 6.0.8.
I'd place this approach in the category "premature optimization". I wouldn't do it that way.

Related

Understanding JSP line of code with getRequestDispatcher

req.getRequestDispatcher("jsp/viewArticles.jsp").forward(req, resp);
So we get the Dispatcher of the Request, and provide the path. Ok so far. Now we forward to it the req and resp.
Now I am lost: We get RequestDispatcher from this req so RequestDispatcher is member method of req. Then why do we need to forward req itself to this RequestDispatcher anyway? Can't this method just use this to access req?
I found a question identical to mine but it do not understand the explanation, this is why I am asking again as an absolute servlet beginner.
How do the getRequestDispatcher() and forward() methods work?
Just for clarification, req and resp are of type HttpServletRequest and HttpServletResponse respectively.
From th API deginition, the RequestDispatcher an object that receives requests from the client and sends them to any resource (such as a servlet, HTML file, or JSP file) on the server. The servlet container (aka Tomcatt) creates the RequestDispatcher object, which is used as a wrapper around a server resource located at a particular path or given by a particular name
The getRequestDispatcher() method is available from the current Request Object or from the current Servlet Context Object . Use req.getRequestDispatcher(path) for a relative path in the same context, and prefer ServletContext.getRequestDispatcher(path) for an absolute path.
Before forwarding you can add parameters Object as attribute with req.setAttribute("key", valueObject ) method to foward parameters server-side . The Request handle the data from the client, you can complete it, and the Response will handle the page, the headers , cookies and so on to the client.
Hope this can help
There's a hint in the JavaDoc of RequestDispatcher:
The difference between this method and ServletContext.getRequestDispatcher(java.lang.String) is that this method can take a relative path.
So essentially, you can ask for the RequestDispatcher via the ServletContext, in which case you can only use absolute paths, or you can request it via the ServletRequest, in which case you can use paths relative to that request path.

The url works in localhost but not in server

I use getServletContext().getRequestDispatcher("/message.jsp").forward(request, response); to forward from servlet to jsp, but this does not work in server. I used response.sendRedirect(request.getContextPath() + "/message.jsp"); but then jsp does not show the message which I send from servlet. How to solve it?
If you do a sendRedirect instead of a forward, you will create a new request, which will cause your request attributes to be gone. Some frameworks use a 'flash' scope (essentially 2 times a request) instead of the request or session scope to handle this. In your case, however, there is no flash scope since you are using plain Servlets/JSP.
Instead, you can do something like:
ServletContext context = getServletContext().getContext(request.getContextPath());
RequestDispatcher dispatcher = context.getRequestDispatcher("/message.jsp");
dispatcher.forward(request, response);
Which should forward the current request to the message.jsp.
you can do by this way
request.setAttribute("PARAM1", "VALUE1");
RequestDispatcher dispatcher = request.getRequestDispatcher("message.jsp");
dispatcher.forward(request, response);
and in your Message.jsp retrieve your set value.
request.getAttribute("PARAM1");

different url after calling a servlet [duplicate]

This question already has answers here:
RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()
(9 answers)
Closed 5 months ago.
I have A servlet that does some stuff, when it has done puts some things in the request and after calls another servlet which in turn calls a jsp page.
I write the code:
first servlet (InserisciLezione)
request.getRequestDispatcher("/TakeDates").forward(request, response);
second servlet (TakeDates)
RequestDispatcher dispatcher = request
.getRequestDispatcher("GestioneCalendario.jsp");
dispatcher.forward(request, response);
This works properly but the problem is that in the url of the page I have yet:
http://localhost:8080/Spinning/InserisciLezione?data=20-02-2013
and If I refresh the page the first servlet is called again and I don't want this.
I would like to have
http://localhost:8080/Spinning/GestioneCalendario.jsp
Why?
thanks in advance!
If my memories are good (it's been a long time I didn't use raw servlets), you should use a redirect rather than a forward.
You can use the response.sendRedirect(url) method.
The RequestDispacher interface provides the facility of dispatching the request to another resource it may be html, servlet or jsp.This interface can also be used to include the content of antoher resource also. It is one of the way of servlet collaboration.
In your case ,you are getting this
http://localhost:8080/Spinning/GestioneCalendario.jsp
because of this servlet
RequestDispatcher dispatcher = request
.getRequestDispatcher("GestioneCalendario.jsp");
dispatcher.forward(request, response);
Page refresh will always redirect you to that url by which servlet you have used. Its like calling an ajax event.
Anyway I can see you dont need to use forward method,try to use
response.sendRedirect(your_url);

Why do I need an HttpSession to get the ServletContext?

In the Java Servlet API, the only way to get the ServletContext is through an instance of HttpSession (Javadoc).
What if I don't want to create a session and only need the servlet context? In other words, why is there no getServletContext() method in the HttpServletRequest class?
EDIT
I know I can get the ServletContext from the servlet itself, since it receives it during its initialization. However, I cannot get it from a HttpServletRequest alone, even though it's linked to a servlet. So what if I have a request, but no reference to any servlet?
getServletContext() is part of GenericServlet which is the parent class for HttpServlet so you should be able to call it in your servlet implementation.
Edit:
HttpServletRequest inherits getServletContext() from ServletRequest since servlet 3.0, so it looks like you will have to pass a context along with the request and response objects if you have to use a version prior to 3.0.
It's just that every entity working with requests (servers, filters, pages) has its own getServletContext (or init())
Your servlet class has a getServletContext() method you don't need to go to the request.
This makes sense, the servlet itself has a context provided by the container, this is independent of any particular request.

How to forward request from web1/servlet to web2/servlet?

I've two web applications say web1 and web2. I want to forward a request from web1/servlet1 to web2/servlet2. Is it possible? Please help!
This is a two-step process:
Get hold of the ServletContext representing web2
Get the RequestDispatcher from that ServletContext corresponding to servlet2
So, something like this, from inside servlet1:
ServletContext web1 = getServletContext();
ServletContext web2 = web1.getContext("/web2");
RequestDispatcher dispatcher = web2.getRequestDispatcher("/servlet2");
dispatcher.forward(request, response);
There's a big caveat to all of this - the container may not be configured to permit cross-context forwarding, since it's a potential security risk. If this is the case, getContext("web2") will return null.

Categories