aspose file tools*
The moose likes Servlets and the fly likes RequestDispatcher Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Servlets
Bookmark "RequestDispatcher" Watch "RequestDispatcher" New topic
Author

RequestDispatcher

Hari Haran
Greenhorn

Joined: Aug 23, 2003
Posts: 10
I am using RequestDispatcher to do some work but was in trouble. What I am doing is finishing some preliminary work in one servlet, then asking the other servlet to take the responsibility for the response. Following is part of my code:
//in the preliminary servlet
public void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException
{
......
// get some information from the request then dispatch it
ObjectInputStream in= new ObjectInputStream(req.getInputStream());
......
getContext().getRequestDispatcher("/servlet/NextServlet").forward(req,resp);
......
}
//in the NextServlet
public void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException
{
....
ObjectInputStream in= new ObjectInputStream(req.getInputStream()); //throws run-time exception
....
}
If I did not get InputStream in the preliminary servlet, everything works fine. But if I do in the above way, I always get the run-time exception. Do I have any way to work around this?
Thanks.
Tony Alicea
Desperado
Sheriff

Joined: Jan 30, 2000
Posts: 3222
    
    5
You can't commit output and ask for a RequestDispatcher.forward(). The first Servlet has to stay away from doing output to the client if it's going to forward later:
"You cannot use forward if the target resource has already returned a ServletOutputStream or PrintWriter object to the servlet. In that situation, forward throws an IllegalStateException."
And it gets more complicated. Servlets 2.1 don't allow the forwarding of POST requests no matter what. Only GETs. Servlets 2.2 (as performed by Jakarta-Tomcat 3.1) do allow forwarding of a POSTs.


Tony Alicea
Senior Java Web Application Developer, SCPJ2, SCWCD
Hari Haran
Greenhorn

Joined: Aug 23, 2003
Posts: 10
Thank you very much!
sudhakar kandasamy
Greenhorn

Joined: Dec 09, 2007
Posts: 4
to solve this problem i will show another way.
You just put your data in a bean.then you set attribute like
req.setAttribute("aliasname",beanname);
this.getServletContext().getRequestDispatcher().forward(req,res);
in second servlet you can access the ben by using getParameter("aliasname).
blue sky
Greenhorn

Joined: Jul 20, 2003
Posts: 12
Hi all!
I have code like this
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, java.io.IOException {
PrintWriter out = resp.getWriter();
resp.setContentType("text/html");
out.print("<HTML>");
out.print("<body>");
out.print("forwarding..................." );
out.print("</body></html>");
out.close();
RequestDispatcher disp= req.getRequestDispatcher"/servlet/include");
disp.forward(req,resp);
}
and in include.java file
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, java.io.IOException
{
PrintWriter out = resp.getWriter();
out.print("<html><BODY>forwared.......... ");
out.print("</body></html>");
out.close();
}
it works fine!. but I know that "forward method can be called only if output not commited to the client yet otherwise IllegalStateException thrown"
So I wonder how can we call "response commited to the client ???"
if yes please give me an example about the way we do to make "response commited to the client"
thanks in advance!
nick zhao
Greenhorn

Joined: Oct 10, 2003
Posts: 3
Hi there,
I think the IllegalStateException exception is propagated up to the servlet container. Adding a try-catch block to catch the exception explicitly is a way to examine your result. Or you can check the terminal window for error & exception messages.
Could anyone tell me the difference between Response.sendRedirect() and RequestDispather.forward().
Kevin Jones
Author
Ranch Hand

Joined: Oct 29, 2003
Posts: 39
Trang. In your code the servlet container is probably throwing away your first servlet's output. Do you see the text 'forwarding...' in the output? Containers are free to buffer output, so if you send output and then do the forward the container will either throw an exception if it has committed the output, or it will simply throw away the data it has bufered.
If you want to mix output from two servlets use RequestDispathcer.forward() not RequestDispatcher.include(), so
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, java.io.IOException {
PrintWriter out = resp.getWriter();
resp.setContentType("text/html");
out.print("<HTML>");
out.print("<body>");
RequestDispatcher disp= req.getRequestDispatcher"/servlet/include").include(req, resp);
out.print("</body></html>");
}
and in include.java file
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, java.io.IOException
{
PrintWriter out = resp.getWriter();
out.print("forwared.......... ");
}
Don't close the streams (the container will do it for you)
Don't output the HTML and body tags in both streams.
BTW - coding servlets this way is a really bad idea. You should put your UI into a JSP (or whatever markup language you choose to use) not into a servlet.


Kevin Jones<br />Author: <a href="http://www.amazon.com/exec/obidos/tg/detail/-/0321136497/jranch-20" target="_blank" rel="nofollow">Servlets and JSP: The J2EE Web Tier</a>
Kevin Jones
Author
Ranch Hand

Joined: Oct 29, 2003
Posts: 39
Nick,
a forward works within the web server. i.e. when you do a forward it is like you are making a method call to another servlet. Essentially what happens is that the container gets a reference to the other servlet and calls it's service method, this is not exactly what happens but it's close enough.
An redirect causes the web server to send a 30x response back to the web browser and the browser sends an entirely new request to the server. This involves an extra roundtrip between the client and the server. It also causes new request and response objects to be created, which means that any attributes stored in the request object get lost.
Malli Raman
Ranch Hand

Joined: Nov 07, 2001
Posts: 312
My Observations:
1) requestDispatcher.forwared(req,response)
a) only the request and response object is forwarded to the new request servlet.
b) If Printwriter object is avaialble in the requested servlet then whatever out.println available in the first servlet is SUPRESSED and it is not throwing any exception.
c) Even if the PrintWriter object is not available in the requested servlet then whatever out.println available in the first servlet is SUPPRESSED.

2) requestDispatcher.include(request,response)
a) I am not sure whether the request and response of second servlet is included in the first Servlet !!!.
b) If the Printwriter object is available in the first servlet then all out.println of the first servlet are DISPLAYED and Second Servlet out.println details are SUPRESSED.
c) If the Printwriter object is not available in the first servlet then all the out.println of the second servlet are DISPLAYED.
Regards,
M.S.Raman
Kevin Jones
Author
Ranch Hand

Joined: Oct 29, 2003
Posts: 39
Nope sorry,
The same PrintWriter/ServletOutputStream is available ot both servlets.
The ouput from the second servlet is not suppressed. If you do a RD.include, output from all servlets is sent back to the client
blue sky
Greenhorn

Joined: Jul 20, 2003
Posts: 12
Hi everybody, Hi Jones!
Thanks for your reply
But could you please explain clearly about "if you send output and then do the forward the CONTAINER WILL EITHER THROW AN EXCEPTION IF IT HAS COMMITED THE OUT PUT"?. I just don't know what is output HAS COMMITED THE OUT PUT?. if yes you can give me an example code use forward() that it throw IllegalStateException
Thanks
Malli Raman
Ranch Hand

Joined: Nov 07, 2001
Posts: 312
Originally posted by Kevin Jones:
Nope sorry,
The same PrintWriter/ServletOutputStream is available ot both servlets.
The ouput from the second servlet is not suppressed. If you do a RD.include, output from all servlets is sent back to the client

Hi Kevin,
Even I expected the same result, but it was showing the output of the first servlet but it is not showing the output for the second servlet ( I used the above code only). I'll check it again.
Regards,
M.S.Raman
Malli Raman
Ranch Hand

Joined: Nov 07, 2001
Posts: 312
Originally posted by Malli Subramanian Raman:

Hi Kevin,

What you said is correct, if i comment out the out.close() in the first servlet it is working fine.
Regards,
M.S.Raman


------------------------- FirstServletForInludeServlet --------------------
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class FirstServletForInludeServlet extends HttpServlet
{
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, java.io.IOException
{
PrintWriter out = resp.getWriter();
resp.setContentType("text/html");
out.print("<HTML>");
out.print("<body>");
out.print(" ***** FirstServletForInludeServlet ***** forwarding..................." );
out.print("</body></html>");
//out.close();
RequestDispatcher disp= req.getRequestDispatcher("/IncludeServlet");
disp.include(req,resp);
}

}
----------------------------IncludeServlet----------------------------------

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class IncludeServlet extends HttpServlet
{
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, java.io.IOException
{
PrintWriter out = resp.getWriter();
out.print("<html><BODY> **** IncludeServlet ***** forwarded.......... ");
out.print("</body></html>");
out.close();
}
}
-------------------------- output ----------------------------------------
***** FirstServletForInludeServlet ***** forwarding................... **** IncludeServlet ***** forwarded..........
Kevin Jones
Author
Ranch Hand

Joined: Oct 29, 2003
Posts: 39
Hi everybody, Hi Jones!
Thanks for your reply
But could you please explain clearly about "if you send output and then do the forward the CONTAINER WILL EITHER THROW AN EXCEPTION IF IT HAS COMMITED THE OUT PUT"?. I just don't know what is output HAS COMMITED THE OUT PUT?. if yes you can give me an example code use forward() that it throw IllegalStateException
Thanks

When you write to the ServletOutputStream/PrintWriter the server creates a buffer, the data you write is put into that buffer. Once that buffer is full the server then sends the output back to the client, this is what I mean by 'committing the output'. The size of the buffer is set initially by the server but can be changed by your code. Look at for details.
blue sky
Greenhorn

Joined: Jul 20, 2003
Posts: 12
Thanks very much!
I've found the answer about response commited
- First, as you explain : Once that buffer is full the server then sends the output back to the client, this is what I mean by 'committing the output'
- Second, use out.flush() to explicit send response to the client
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: RequestDispatcher