• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

RequestDispatcher

 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Desperado
Posts: 3226
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Hari Haran
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you very much!
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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).
 
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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!
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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().
 
Author
Posts: 39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Author
Posts: 39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic