Link to home
Start Free TrialLog in
Avatar of Triggered
Triggered

asked on

Redirectiong from servlets.

Hi,

Im having problems trrying to redirect from a servlet to a jsp page from within a "doPost()" method,
im new to servlets , my code for the redirect is:

 RequestDispatcher Dispatche=request.getRequestDispatcher("http://localhost:8080/myJSPpage.jsp");
        Dispatche.forward(request,response);


im getting errors though,im wondering where am i going wrong here.

Thanks in advance,
Triggered
Avatar of bobbit31
bobbit31
Flag of United States of America image

for a simple redirect:

response.sendRedirect("http://localhost...");
Avatar of rrz
>from a servlet to a jsp page    
Are they both in the same context ?  
If they are located in the same context, then you can use a relative path.

RequestDispatcher Dispatche=request.getRequestDispatcher("/myJSPpage.jsp");  

this assumes that myJSPpage.jsp is located in the current context's  root directory.
Avatar of Triggered
Triggered

ASKER

tried that already bbit31 but i get erros:

java.lang.IllegalStateException

      at org.apache.catalina.connector.HttpResponseFacade.sendRedirect(HttpResponseFacade.java:173)
can you post your complete servlet code?
tried that rrz@871311

but im getting the following errors:-


StandardWrapperValve[invoker]: Servlet.service() for servlet invoker threw exception

java.lang.IllegalStateException: Cannot forward after response has been committed

java.lang.IllegalStateException: Cannot forward after response has been committed

      at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:367)

      at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:355)
You can not redirect after response has started.  You could increase buffer size if necessary.  rrz
for example  
<%@ page buffer="12kb" %>
how do i increase the page buffer size in a servlet
that's kind of a kludge... if you were to just post your servlet code, there is i'm sure an easy solution.
heres the basic outline of the servlet servlet:


import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;



public class BidServlet extends HttpServlet {
  private static final String CONTENT_TYPE = "text/html";
  //Initialize global variables
  public void init() throws ServletException {
  }
  //Process the HTTP Get request
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
   }

  public void doPost( HttpServletRequest request, HttpServletResponse response)
   throws  ServletException, IOException
  {




 

   //   String url = "http://localhost:8080/myAccount.jsp";
    //  RequestDispatcher Dispatche=request.getRequestDispatcher("http://localhost:8080/myAccount.jsp");
    //    Dispatche.forward(request,response);



    RequestDispatcher Dispatche=request.getRequestDispatcher("/myAccount.jsp");
     Dispatche.forward(request,response);
   //  response.sendRedirect("http://localhost:8080/myAccount.jsp");




      //response.sendRedirect("http://localhost:8080/myAccount.jsp");
  }
  //Clean up resources
  public void destroy() {
  }
}
SOLUTION
Avatar of rrz
rrz
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
first of all, whenever you are overridding init() you need to do this:

    public void init (ServletConfig config) throws ServletException {
        super.init(config);
    }

also, i don't notice you writing anything to response... so either should work:

// try w/o slash
RequestDispatcher Dispatche=request.getRequestDispatcher("myAccount.jsp");
     Dispatche.forward(request,response);

OR

response.sendRedirect("http://localhost:8080/myAccount.jsp");



If you get the writer or the output stream from the response, you can no longer redirect...
You've pasted the basic outline... have you by any chance missed out calls to:

response.getWriter() or response.getOutputStream()
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
oops, misread the code ;)
I would suggtest you to include instead of forward since you don't output anything in your sevlet.
RequestDispatcher Dispatche=request.getRequestDispatcher("myAccount.jsp");
     Dispatche.include(request,response);

In addition, I case you didn't post the real servlet, we need the full/real servlet code to identify your problem.
IllegalState exception will be thrown only if your outputstream is already in use somewhere else prior to forwarding i.e. you have written
response.getWriter() or response.getOutputStream()
some where in the code prior to forwarding ( sendRedirect should still work because as far as I know its a client side redirect i.e. server sends a redirect request to the browser instead of redirect himself).

As other experts are suggesting, post your full code and we might find something in there.

Regards
heres the code guys:


package racehorseproj;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import racehorseproj.NotifyOwner;
import racehorseproj.DBConectionManager;
import racehorseproj.*;


public class BidServlet extends HttpServlet {
  private static final String CONTENT_TYPE = "text/html";
  //Initialize global variables
  public void init() throws ServletException {
  }
  //Process the HTTP Get request
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   // response.setContentType(CONTENT_TYPE);
   // PrintWriter out = response.getWriter();
   // out.println("<html>");
   // out.println("<head><title>BidServlet</title></head>");
   // out.println("<body bgcolor=\"#ffffff\">");
   // out.println("<p>The servlet has received a GET. This is the reply.</p>");
   // out.println("</body></html>");
  }

  public void doPost( HttpServletRequest request, HttpServletResponse response)
   throws  ServletException, IOException
  {


      HttpSession session = request.getSession();
      String HorseID = (String)session.getAttribute("HorseID");
            System.out.println("\nHorseID="+HorseID);

      String MemberID = (String)session.getAttribute("MemberID");
      String option = String.valueOf(request.getParameter("option"));
      System.out.println("\noption="+option);




      DBConectionManager dbCon = new DBConectionManager();
      Horse HorseDetails = new Horse();

      String bidAmount = String.valueOf(request.getParameter("BidAmount"));

 System.out.println("\nHorseID="+HorseID+"  ,MemberID"+MemberID+" ,bidAmount"+bidAmount);

dbCon.storeBid(Integer.parseInt(HorseID),Integer.parseInt(MemberID),Integer.parseInt(bidAmount));



 HorseDetails = dbCon.GetHorseProfile(Integer.parseInt(HorseID));
 String HorseOwnersID  =HorseDetails.getOwnerID();

 System.out.println("\nHorseOwnersID="+HorseOwnersID);

 Hashtable OwnersDetails = new Hashtable();
          OwnersDetails  =  dbCon.GetMemberProfile(Integer.parseInt(HorseOwnersID));

  String OwnersEmailAddress = (String)OwnersDetails.get("EmailAddress");


 Hashtable BidderDetails = new Hashtable();
            BidderDetails  =  dbCon.GetMemberProfile(Integer.parseInt(MemberID));

  String BiddersEmailAddress = (String)BidderDetails.get("EmailAddress");

  System.out.println("\n\nThe person that bid,email="+BiddersEmailAddress);
  System.out.println("\n\nThe person that owns the horse,email="+OwnersEmailAddress);
  System.out.println("\n\nThe bid amount,bid amount="+bidAmount);


      NotifyOwner.SendSMS("353879903803","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!",request.getInputStream(),response.getOutputStream(),request.getContentType());
      NotifyOwner.SendEmail("bids@racingocus.com",BiddersEmailAddress," Bid Made or Horse","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!");

      session.setAttribute("BidDetails","An SMS text message and email have been to sent to the owner informing him/her of your bid");

 

   RequestDispatcher Dispatche=request.getRequestDispatcher("myAccount.jsp");
        Dispatche.include(request,response);





  }
  //Clean up resources
  public void destroy() {
  }
}
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
the problem is in NotifyOwner.SendSMS, in which you pass response.getOutputStream() object to it. what did that do?
does it send a response the browser saying that you message is send successfully?
Which version of Tomcat are you using ?
i'm a slow typer :-)
Okay first thing that you can do is to change the init method of yours to be like..
public void init(ServletConfig config) throws ServletException {      
super.init(config);
} //if you are not doing anything in init, atleast the web server do its own stuff...

and secondly try to obtain the requestDispatcher from the servlet context instead of the request.....
RequestDispatcher Dispatche=getServletContext().getRequestDispatcher

something like the above
See if that helps
now i don't know exactly what NotifyOwner.SendSMS does, but if it writes to your response's output stream, you will get an error as stated above.

What i would do is skip the SendSMS and put in:

 RequestDispatcher Dispatche=request.getRequestDispatcher("myAccount.jsp");
        Dispatche.forward(request,response);

and in myAccount.jsp (obviously passing certain variables like bidAmount, horsename, etc... via request.setParameter("bidAmount", new Integer(bidAmount)) as an example:

NotifyOwner.SendSMS("353879903803","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!",request.getInputStream(),response.getOutputStream(),request.getContentType());
      NotifyOwner.SendEmail("bids@racingocus.com",BiddersEmailAddress," Bid Made or Horse","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!");
and oh by the way you are using the outputstreams in both of the methods up there...!!!!
Oooops I am a slow typer too.....:-)
Kuldeepchaturvedi, bobbit31 had already talked about the init method and I commeted on that you should take a look. I also think getting dispetcher from request object is fine, it is very useful when you need relative path.
NotifyOwner() opens a URL to another website,and performs post via a socket to send a SMS,

ill try commenting it out to see if it makes a difference,will be back in a few minutes
that kinda worked,it displays my Account web page, but the top half of the page doesnt display any of the normal images
i have in it + URL in the browser still has "http://localhost:8080/servlet/bidservlet" in it instead of
"http://localhost:8080/myAccount.jsp" ???...

i have to have the NotifyOwner() call though
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>>>i have to have the NotifyOwner() call though

can you move that method call in your farworded jsp????? ( just trying to find a easy way out...!)
the browser still has "http://localhost:8080/servlet/bidservlet", that's how forward works :(

>> NotifyOwner() opens a URL to another website,and performs post via a socket to send a SMS
if that is the case, you should needed to pass the outputstream to it.
change the
response.getOutputStream()
to
new java.io.ByteArrayOutputStream()
see if that fixes the problem.
>>>>>>>> you should needed to pass the outputstream to it.
or should not needed???????
heres my
Notify owner code:


package racehorseproj;



import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
import racehorseproj.DBConectionManager;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.net.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;



public class NotifyOwner {
  public NotifyOwner() {
  }

 static public boolean SendEmail(String SourceAddress,String DestinationAddress,String Subject,String MessageBody) {

   try{
        Properties props = new Properties();
        Session s = Session.getInstance(props);
        MimeMessage message = new MimeMessage(s);
        InternetAddress from = new InternetAddress(SourceAddress);
        InternetAddress to = new InternetAddress(DestinationAddress);

                  props.put("maXXXXX", "XXXXX");
                  message.setFrom(from);
                  message.addRecipient(Message.RecipientType.TO, to);
                  message.setSubject(Subject);
                  message.setText(MessageBody);
                  Transport.send(message);
                  return true;
     }
     catch(Exception e){}


    return false;
  }

 static public boolean SendSMS(String MobileNumber,String Message,InputStream clientInputStream, OutputStream clientOutputStream,String ContentType) {

   try{
     HttpURLConnection con = null;
        URL url = new URL("http://smXXXXXXX.php " );
        con = (HttpURLConnection) url.openConnection();
        con.setRequestProperty("Content-Type", ContentType);
        con.setDoOutput(true);
        con.setDoInput(true);
        con.setRequestMethod("POST");
        OutputStream serverOutputStream = con.getOutputStream();

        String message = "pho="+MobileNumber+"&con="+Message+"&usr=racingfocus&pwd=2XXXXX48&ori=racingfocus";
        serverOutputStream.write( message.getBytes() );

      InputStream serverInputStream = con.getInputStream();
      int c;

      while ( (c = serverInputStream.read()) != -1)
        clientOutputStream.write(c);

        serverInputStream.close();
        clientOutputStream.close();
        serverOutputStream.close();
        con.disconnect();
    }catch(Exception e){
       return false;
    }


   return true;
 }


}

try this:

NotifyOwner.SendSMS("353879903803","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!",request.getInputStream(),new OutputStream(),request.getContentType());
      NotifyOwner.SendEmail("bids@racingocus.com",BiddersEmailAddress," Bid Made or Horse","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!");
>>>>>>>>>>>>>>>>>>
change the
response.getOutputStream()
to
new java.io.ByteArrayOutputStream()
see if that fixes the problem.


----------------------------------------

sorry kennethxu,but response.getOutputStream()  should be causing the problem described above
as the Notify Owner code is commented out
tried that bobbit31 but the compiler is telling me that :-

 java.io.OutputStream()  is an abstract class + cant be instaniated
another way around it (seeing as you want www.blah.com/MyAccount.jsp) to show up in address bar is to store it in session:

e.g.
OutputStream tmpOut = new OutputStream()
NotifyOwner.SendSMS("353879903803","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!",request.getInputStream(),tmpOut,request.getContentType());
      NotifyOwner.SendEmail("bids@racingocus.com",BiddersEmailAddress," Bid Made or Horse","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!");

session.setAttribute("curOutputStream", tmpOut);

then in myAccount.jsp:

you can simply do:

OutputStream myOut = (OutputStream) session.getAttribute("curOutputStream");
>> or should not needed???????
I'm sorry, absolutely should NOT :-)
In the code of notify owner, all you are doing with clientoutputstream is closing it!!!
Why is it necessary?? just don't send it and don't close it inside sendSMS method!!!
actually, he does write to it:
>>>    clientOutputStream.write(c);
Ooops.... you are writing the response as welll....

I would rather keep that response in a string buffer and then dump the stringbuffer in the session maybe..
Or keep it in the bean itself...

After that when I farword it to the jsp then I can get the StringBuffer back from either session or from bean and then write it out in the jsp....

if you are going to be storing in a session var, i'd use sendRedirect instead of forward (that way myAccount.jsp will show up in address bar)
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Why not change your method  to return String

static public String SendSMS(String MobileNumber,String Message,InputStream clientInputStream,String ContentType) {

and in your servlet

out.println(NotifyOwner.SendSMS(String MobileNumber,String Message,InputStream clientInputStream,String ContentType);
sorry kennethxu,

i tried that and it forwards to "myAccount.jsp" page BUT theres a problem i havent seen before,
"myAccount.jsp" justs displays the text part of the page, ie the images i have at the top arent displaying at all:

the following mesage is given by the compiler:

StandardWrapper[:org.apache.catalina.INVOKER.jpeg]: Marking servlet org.apache.catalina.INVOKER.jpeg as unavailable

i have a folder named "jpeg" with images in it i use for banners and buttons/links,

any idea whats causing it




oops forgot a ")" at the end of last line.   rrz
If I have to combine all the suggestion that i have had up above I will write the code something like this...
ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();
String res=  NotifyOwner.SendSMS("353879903803","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!",request.getInputStream(),bout,request.getContentType());
      NotifyOwner.SendEmail("bids@racingocus.com",BiddersEmailAddress," Bid Made or Horse","A bid of "+bidAmount+" Euro Has been Made for your Horse("+HorseDetails.getHorseName()+"),for more info on this bid log on to your account at www.racingfocus.net now!");


inside the NotifyOwner..

static public String SendSMS(String MobileNumber,String Message,InputStream clientInputStream, OutputStream clientOutputStream,String ContentType) {

   try{
     HttpURLConnection con = null;
        URL url = new URL("http://smXXXXXXX.php " );
        con = (HttpURLConnection) url.openConnection();
        con.setRequestProperty("Content-Type", ContentType);
        con.setDoOutput(true);
        con.setDoInput(true);
        con.setRequestMethod("POST");
        OutputStream serverOutputStream = con.getOutputStream();

        String message = "pho="+MobileNumber+"&con="+Message+"&usr=racingfocus&pwd=2XXXXX48&ori=racingfocus";
        serverOutputStream.write( message.getBytes() );

      InputStream serverInputStream = con.getInputStream();
      StringBuffer response = new StringBuffer();
                  String line;
      
                  while ((line = serverInputStream.readLine()) != null)
                        response.append(line);
                  in.close();
        serverInputStream.close();
        serverOutputStream.close();
        con.disconnect();
    }catch(Exception e){
       return null;
    }


   return response.toString();
 }


Now back in the servlet

RequestDispatcher Dispatche=request.getRequestDispatcher("myAccount.jsp?Res="+res);
        Dispatche.include(request,response);
ofcourse assuming that response is not more that 255 bytes or whatever the heck webservers allow on the querystring....
Thats the quixk and dirty way of getting it done..
I wd still like to go with my previous suggestion of either bean or a session value for this string
i have a folder named "jpeg" with images in it i use for banners and buttons/links,
replace the dispatcher with
response.sendRedirect("/myJSPpage.jsp");
might fix this problem.
I don't see much benefit of changing the NotifyOwner. fixing the servlet with ByteArrayOutputStream should be sufficient.
I think he needs the response to be shown to the user... once the response is written to new ByteArrayOutputStream, what he will do with it??
kuldeep, I think we are going  a similar way.  
Now, there is no need to pass  clientOutputStream  to  NotifyOwner
he can do whatever he like to the ByteArrayOutputStream. it contains the information returned from the sms server. so there is no need to change the NotifyOwener, isn't it?
I would not change the NotifyOwner interface because it looks like an utility class so it could be used in other places of the system.
that worked kennethxu,
Thanks a million :-)
I think we all agree that the root cause of his problem is the outputstream. Now its just a matter of ways of implementation...
I think both ways will work, now it depends on triggerred which way he feels comoftable...

I think He was having problems with his relative paths of images and links when he farword to the jsp page ( which I reckon he will because forward won't change the url of browser and hence will mess up the relative paths.) sendredirect will be more suitable for him...
and correct me if I am wrong.. if he is using sendRedirect it really doesn't matter him the outputstream is already commited because sendRedirect actually sends a HTTP header to the Browser and then brwoser does the actual redirect request....!
>> sendRedirect actually sends a HTTP header to the Browser
if the output is commited, you cannot send the http header either!
>> that worked kennethxu,
great!
please splite points :-)
I meant SPLIT points to people here.
haha :-)  forgot about the points in the excitement, thanks a million for the help evryone, hope i dont offend anyone
with the way i split the points
I was a good discussion to be a part with... I am even okay if I don't get points.....:-)
oops Kuldeepchaturvedi, i forgot to include you....

ADMIN could you please award 60 points  to Kuldeepchaturvedi (by dedeuction 20 points each of the accepted solution(s))
Well you know what!!! You have already awarded me point...!!!! so if you wanna do it again.. I certainly won't mind it....(chuckles)
haha :-)  .... its been a long day here, need to get away from the pc for a few hours

ADMIN please ignore my last post