1

The idea behind this is that i'll be redirecting to a page if the login(correct user+pass) exsists in my database and upon this authentication, they can store a message in a text file.The code is pretty straightforward though I'm not sure as to why I'm getting an IllegalStateException

This is my- logininfo.java

public class logininfo extends HttpServlet 
{   private static final long serialVersionUID = 1L;

     //I've hidden all the unused code

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
    String user= request.getParameter("user");
    String pass= request.getParameter("pass");
    response.setContentType("text/html");
    PrintWriter pw = response.getWriter();
    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;


        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            con=DriverManager.getConnection("jdbc:mysql://localhost:3306/mayurtest","root","root");
            String sql = "SELECT * FROM LOGIN where user=? and pass=?";   //thanks braj
            stmt = con.prepareStatement(sql);
            stmt.setString(1, user); 
            stmt.setString(2, pass); 
            rs = stmt.executeQuery();
            while(rs.next())
            {
                if((rs.getObject(1).toString().equals(user))&&(rs.getObject(2).toString().equals(pass)))     //edited code
                {   
                         pw.println("correct login");                   
                         response.sendRedirect("message.HTML");  //request.getRequestDispatcher("message.html").include(request,response); is what I should write instead
                    String message=request.getParameter("message");   //error here???? /*seems to be a problem as now all I get are null values printed*/ 
                    testmessage(message);                   
                    break;  
                }
                else
                {
                    pw.println("please check username/password again.<br>");
                    response.sendRedirect("userlogininfo.HTML");//request.getRequestDispatcher("userlogininfo.html").include(request,response); is what I should write instead
                    break;
                }
            }


        }


        }
        catch (SQLException e) 
        {
            pw.println(e.getNextException());
        } 
        catch (ClassNotFoundException e)
        {
            pw.println(e.getException());
        } 
        finally 
        {
            try
            {
                if (rs != null) {
                    rs.close();
                    rs = null;
                }
                if (stmt != null) {
                    stmt.close();
                    stmt = null;
                }
                if (con != null) {
                    con.close();
                    con = null;
                }
            } 
            catch (Exception e)
            {
            pw.close();
            }

        }   


    }





    public void testmessage(Connection con,Statement stmt,ResultSet rs,String message) throws FileNotFoundException
    {
        File file = new File("C:/Users/thammaiahm/Desktop/mayur desktop files/mayur.txt");
        FileReader fr = new FileReader(file);
        try{

            PrintWriter pw1 = new PrintWriter(new    
            FileOutputStream("C:/Users/thammaiahm/Desktop/mayur desktop files/mayur.txt",true));  
            pw1.println( message ); 
            pw1.close();
            fr.close();

        }
        catch(IOException ioio){//do something
            }
      }
}

This is now followed by the two HTML pages- userloginpage.HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>Enter the login details<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"></head>

<body>
<form method="post" action="http://localhost:8888/Servlet/logininfo">
Login   :<input type="text" name="user"/><br>
Password:<input type="password" name="pass"/><br>
<input type="submit" value="login"/>


</form></body>
</html>

and message.HTML->>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>Welcome user: 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"></head>

<body>
<form method="post" action="http://localhost:8888/Servlet/logininfo">
Please enter you secret message:<input type="text" name="message"/><br>
<input type="submit" value="login"/>
</form></body>
</html>

Can you help me find the error? And maybe help me out on any programming practices I should follow?

  • Does your IllegalStateException give a stack trace? They are very useful in finding where the problem lies without analyzing the code line-by-line. –  Jun 20 '14 at 07:03

4 Answers4

3

Here is the complete exception message:

java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed

It's clear from the exception where is the problem.

When sendRedirect() is called it means now the HTML response will be generated by another redirected HTML/JSP/Servlet but before doing this some response has already sent to client that can't be reverted.

If you want to include the response of another HTML/JSP/Servlet then use forward or include instead of sendRedirect.

For e.g

request.getRequestDispatcher("message.html").include(request,response);

There is no need to fetch all the records from the table. you can fetch only single record based on username and password using PreparedStatement

Sample code:

String sql = "SELECT * FROM LOGIN where username=? and password=?";

stmt = con.prepareStatement(sql);
// Bind values into the parameters.
stmt.setString(1, user); // This would set username
stmt.setString(2, pass); // This would set password
rs = stmt.executeQuery();
if (rs.next()) {
    pw.println("correct login");
    request.getRequestDispatcher("message.html").include(request, response);
    ...
} else {
    pw.println("please check username/password again.<br>");
    request.getRequestDispatcher("userloginpage.html").include(request, response);
}

Note: Don't load the driver class every time you need a new connection. Create a separate class for connection management.

I have already posted a nice ConnectionUtil class to manage all the connections in a single class for whole application.

Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
  • I did use your advice, the code does work (in part). However I am getting NULL printed into the text file.(I also beleive that sometimes the TOMcat server is faulty.I needed to close my Eclipse application a couple of times to get it running.) Any suggestions on improving my code?For example, I have done away with the use of FLAG1 and FLAG2 and the redundant 'if' clauses. –  Jun 20 '14 at 07:45
  • At least the root cause is fixed? Just debug your code It's very easy to find the problem. – Braj Jun 20 '14 at 07:48
  • while loop must be break after calling include or forward that is missing in else part. – Braj Jun 20 '14 at 07:51
  • Look at my updated post for further improvement in the JDBC code. – Braj Jun 20 '14 at 07:55
1

Here's the main problem:

pw.println("correct login");
response.sendRedirect("message.html");

and

pw.println("please check username/password again.<br>");
response.sendRedirect("userloginpage.html");

You are writing to pw that is the response writter (PrintWriter pw = response.getWriter();) and calling redirect.

If you print something tohttp://stackoverflow.com/questions/24321638/login-based-application-which-produces-illegalstateexception/24321944# the response you can't redirect to another page and if you redirect you must not print data to the response.

Dubas
  • 2,855
  • 1
  • 25
  • 37
  • Isn't it the same answer that I have posted? – Braj Jun 20 '14 at 07:21
  • 1
    Yes, I beleive there may be another problem in the 'testmessage' method. IllegalStateException may also occur with PrintWriter and out.println –  Jun 20 '14 at 07:48
  • Yes Braj. We write the answer at same time. But your response appears more complete. Good job. – Dubas Jun 23 '14 at 10:38
1

Dubas is correct. What your doing is sending the reponse via the pw.println and then trying to redirect after the reponse has been started. If you purely want to see if the login is correct then either output the resuls to the log file e.g System.out.println("please check username/password again.
"); and then call your redirect. Or if your trying return the result to the end user you can send the outcome of the login process as a variable in the query statement and then process this on the redirected code:

response.sendRedirect("userloginpage.html?result=SUCCESS"); or response.sendRedirect("userloginpage.html?result=FAIL");

Does the end user need to see if login sucessfull just redirect the page to the desired successful login process.

If you do want the end user to see a page that says something like "Login sucessful. Redirecting..." then what i would suggest is redirect to userloginpage.html passing result and test this in the redirect page and then use a meta redirect:

Redirect from an HTML page

the above explains it well then there no reliant on javascript.

Community
  • 1
  • 1
1

I finally understood where I was going wrong. You see, userlogininfo.HTML and message.HTML are two different forms. Different forms have different requests that they would be sending. 1. userlogininfo- sends the USER/PASS authentication 2. message - sends the "message" to the file on the computer. Herein lies the difference. I ended up changing the format of the code.Though if you understand the code you will just have to understand why this works.

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException   
/*this is used for preprocessor handling as I've read
.Connecting to the database and authenticating the USER/PASS 
in the first form(userlogininfo.HTML) is done here*/
    {
        String user= request.getParameter("user");
        String pass= request.getParameter("pass");
        response.setContentType("text/html");
           PrintWriter pw = response.getWriter();
           Connection con = null;
           PreparedStatement stmt = null;
           ResultSet rs = null;


              try
              {
                Class.forName("com.mysql.jdbc.Driver");
               con=DriverManager.getConnection("jdbc:mysql://localhost:3306/mayurtest","root","root");
               String sql = "SELECT * FROM LOGIN where user=? and pass=?";
               stmt = con.prepareStatement(sql);
               stmt.setString(1, user); 
               stmt.setString(2, pass); 
               rs = stmt.executeQuery();
               while(rs.next())
               {
                if((rs.getObject(1).toString().equals(user))&&(rs.getObject(2).toString().equals(pass)))
                {   
                    doPost(request,response); //this calls the doPost function
                    break;
                }
                else
                {
                    request.getRequestDispatcher("userlogininfo.html").include(request,response);
                    break;
                }
               }


              }
          //followed by various catch statements and exception handling(same code as above).

     }



/*end of doGet and beginning of doPost this enables me to use "request" and "response" for another form(message.HTML)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
        {

            request.getRequestDispatcher("message.html").include(request,response);
            String message=request.getParameter("message");
            File file = new File("C:/Users/thammaiahm/Desktop/mayur desktop files/mayur.txt");
            FileReader fr = new FileReader(file);
            try{
                PrintWriter pw1 = new PrintWriter(new    
                FileOutputStream("C:/Users/thammaiahm/Desktop/mayur desktop files/mayur.txt",true));  
                pw1.println(message); //message is stored in file...
                pw1.close();
                fr.close();
               }
            //more catch exceptions...
            }           

    }

Today has been a learning experience.Comments and thoughts are welcome. If you want to talk about why what I did works,I have no CLEAR understanding myself, but I'm open to discuss what I think happens.

  • THIS IS TO BE USED AS AN EXAMPLE ONLY.IN NO WAY I AM SAYING THAT THIS IS THE BEST METHOD. THANKS FOR ALL THE HELP I GOT ON THIS ONE. CHEERS! –  Jun 24 '14 at 05:45