You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Jason Johnston <Ja...@epa.state.il.us> on 2003/04/22 23:48:18 UTC
Tomcat 4.1.24 :Cannot forward after response has been
committed
I have a cheesy little authentication servlet that's being used to
authenticate users and build a security token from a database and place
it in their session.
Everything was working under tomcat 4.0.1 but I'm running into this
"cannot forward error".
Now, if I don't forward and just dump the debugging results.
Everything works fine. However, the moment I go to forward. It throws
an error.
As far as I can tell, I'm not committing the response anywhere, and
like I said, it worked under the old tomcat.
Here's the code for the Servlet:
/*
* BOAAuthenticate.java
*
* Created on February 6, 2003, 1:39 PM
*/
package boa;
import javax.servlet.*;
import javax.servlet.http.*;
import com.javaexchange.dbConnectionBroker.*;
import java.util.*;
import java.io.*;
import java.sql.*;
import boa.person;
import boa.SecurityToken;
import boa.BOARight;
/**
* BOAAuthenticate is going to work as the primary Servlet for
authentication
* services. It will use the existing application-context DataBasePool
and Authenticate
* users based on the username/password combination supplied. It will
then create a
* SecurityToken that holds all pertinent rights for the user and place
it in the
* user's Session. It will then create a "person" object representing
the user and
* place that in the Session as well.
* @author Jason Johnston
* @version 2.0
*/
public class BOAAuthenticate extends HttpServlet {
private DbConnectionBroker pool;
private Connection conn;
private String errorstring="";
private int userdbid;
private boolean success=false;
/** Initializes the servlet and retrieves a handle on the
DatabasePool
*/
public void init(ServletConfig config) throws ServletException {
super.init(config);
pool=(DbConnectionBroker)getServletContext().getAttribute("dbPool");
}
/** Destroys the servlet.
*/
public void destroy() {
}
/**This method takes the DB connection and test the username
* password combo supplied. If successful, returns true.
* To do: account for user not existing or password not existing.
*/
private boolean authenticate(Connection conn,String ui,String pwd)
{
String query="select id from users where user_id='"+ui+"'";
String password="";
try{
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(query);
if(!(rs.next())){
errorstring+=" No results returned <br>";
}
userdbid=rs.getInt("ID");
}catch(SQLException e){
errorstring+=" SQLException Getting DB User ID:"+e+"<br>";
errorstring+=" Query Performed: "+query+"<br>";
}
try{
Statement stmt=conn.createStatement();
query="select * from passwords where id='"+userdbid+"'";
ResultSet rs=stmt.executeQuery(query);
rs.next();
password=rs.getString("password");
//out.print("Retrieved Password: "+password+"<br>");
//out.print("Sent Password: "+pwd+"<br>");
}catch(SQLException e){errorstring+=" SQLException Getting
password:"+e+"<br>";}
if(pwd.equalsIgnoreCase(password))
return true;
else
return false;
}
/** This method builds the security token based on the information
in the
database relating to the userdbid value. */
private SecurityToken buildtoken(Connection con)
{
String sql;
SecurityToken st=new SecurityToken();
try{
Statement stmt=con.createStatement();
sql="select * from security where user_id='"+userdbid+"'";
ResultSet rs=stmt.executeQuery(sql);
while(rs.next())
{
st.addRight(new
BOARight(rs.getString("app_name"),rs.getInt("level")));
}
}catch(SQLException e){errorstring+=" SQLException building
token:"+e+"<br>";}
return st;
}
/** This method builds the person object based on the information
in the
database relating to the userdbid value. */
private person buildperson(Connection con)
{
person tempperson=new person();
try{
Statement stmt=con.createStatement();
String sql="select * from users where id='"+userdbid+"'";
ResultSet rs=stmt.executeQuery(sql);
rs.next();
tempperson.setid(rs.getString("id"));
tempperson.setfname(rs.getString("firstname"));
tempperson.setlname(rs.getString("lastname"));
tempperson.setdivision(rs.getString("udivision"));
tempperson.setsection(rs.getString("usection"));
tempperson.setunit(rs.getString("uunit"));
}catch(SQLException e){errorstring+=" SQLException building
person. ";}
return tempperson;
}
/** Processes requests for both HTTP <code>GET</code> and
<code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException {
success=false;
errorstring="";
String forward=(String)request.getAttribute("forward");
HttpSession session=request.getSession();
if(forward==null)
{
forward=(String) session.getAttribute("forward");
if(forward==null)
{
forward="/debug1.jsp";
}
}
conn=pool.getConnection();
//response.setContentType("text/html");
//java.io.PrintWriter out = response.getWriter();
String[] temparray=request.getParameterValues("userid");
String[] temparray2=request.getParameterValues("password");
if((temparray==null)||(temparray2==null))
{
errorstring="Sorry, you didn't supply a userid or password.";
request.setAttribute("error",errorstring);
request.setAttribute("forward",forward);
RequestDispatcher
rd=getServletContext().getRequestDispatcher("/login.jsp");
rd.forward(request,response);
//out.print("Forward: "+forward);
}
else
{
String userid=temparray[0];
String password=temparray2[0];
if(authenticate(conn,userid,password))
{
success=true;
SecurityToken st=buildtoken(conn);
person user=buildperson(conn);
request.getSession().setAttribute("security",st);
request.getSession().setAttribute("person",user);
}
}
//out.print("Errors: "+errorstring+"<br>");
//out.print("Userid: "+userid+"<br>");
// out.print("Password: "+password+"<br>");
//out.print("Userdb ID:"+userdbid+"<br>");
//out.print("Authentication: "+success+"<br>");
//out.print("Forward: "+forward+"<br>");
//out.close();
request.setAttribute("error",errorstring);
RequestDispatcher
rd=getServletContext().getRequestDispatcher(forward);
rd.forward(request,response);
}
/** Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException {
processRequest(request, response);
}
/** Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException {
processRequest(request, response);
}
/** Returns a short description of the servlet.
*/
public String getServletInfo() {
return "Servlet for authenticating to BOA webapps";
}
}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
End of source code
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
Here's the stack trace that the servlet dumps:
java.lang.IllegalStateException: Cannot forward after response has been
committed
at
org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:368)
at
org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:356)
at boa.BOAAuthenticate.processRequest(BOAAuthenticate.java:185)
at boa.BOAAuthenticate.doGet(BOAAuthenticate.java:196)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.servlets.InvokerServlet.serveRequest(InvokerServlet.java:466)
at
org.apache.catalina.servlets.InvokerServlet.doGet(InvokerServlet.java:180)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at
org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:594)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:392)
at
org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:565)
at
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:619)
at java.lang.Thread.run(Thread.java:536
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
End of stack trace
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
I'm am currently maping servlets for this application to the "invoker"
via the web.xml. I'm doing this to make them work again and I haven't
seen anyone list any alternatives.
Thanks ahead of time for anyone that has any insight.
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
Re: Tomcat 4.1.24 :Cannot forward after response has been committed
Posted by Tim Funk <fu...@joedog.org>.
You are forwarding twice in processRequest()
protected void processRequest(...){
...
if((temparray==null)||(temparray2==null)) {
rd.forward(request,response);
return ; /* PUT RETURN HERE TO AVOID ERROR
If not the extra forward() is performed
below and boom- your error
*/
} else {
... stuff ...
}
...
request.setAttribute("error",errorstring);
RequestDispatcher rd=getServletContext().getRequestDispatcher(forward);
rd.forward(request,response);
}
-Tim
Jason Johnston wrote:
> I have a cheesy little authentication servlet that's being used to
> authenticate users and build a security token from a database and place
> it in their session.
>
> Everything was working under tomcat 4.0.1 but I'm running into this
> "cannot forward error".
>
> Now, if I don't forward and just dump the debugging results.
> Everything works fine. However, the moment I go to forward. It throws
> an error.
>
> As far as I can tell, I'm not committing the response anywhere, and
> like I said, it worked under the old tomcat.
>
> Here's the code for the Servlet:
>
> /*
> * BOAAuthenticate.java
> *
> * Created on February 6, 2003, 1:39 PM
> */
>
> package boa;
>
> import javax.servlet.*;
> import javax.servlet.http.*;
> import com.javaexchange.dbConnectionBroker.*;
> import java.util.*;
> import java.io.*;
> import java.sql.*;
> import boa.person;
> import boa.SecurityToken;
> import boa.BOARight;
> /**
> * BOAAuthenticate is going to work as the primary Servlet for
> authentication
> * services. It will use the existing application-context DataBasePool
> and Authenticate
> * users based on the username/password combination supplied. It will
> then create a
> * SecurityToken that holds all pertinent rights for the user and place
> it in the
> * user's Session. It will then create a "person" object representing
> the user and
> * place that in the Session as well.
> * @author Jason Johnston
> * @version 2.0
> */
> public class BOAAuthenticate extends HttpServlet {
> private DbConnectionBroker pool;
> private Connection conn;
> private String errorstring="";
> private int userdbid;
> private boolean success=false;
>
> /** Initializes the servlet and retrieves a handle on the
> DatabasePool
> */
> public void init(ServletConfig config) throws ServletException {
> super.init(config);
>
> pool=(DbConnectionBroker)getServletContext().getAttribute("dbPool");
> }
>
> /** Destroys the servlet.
> */
> public void destroy() {
>
> }
>
>
> /**This method takes the DB connection and test the username
> * password combo supplied. If successful, returns true.
> * To do: account for user not existing or password not existing.
>
> */
> private boolean authenticate(Connection conn,String ui,String pwd)
> {
> String query="select id from users where user_id='"+ui+"'";
> String password="";
> try{
> Statement stmt=conn.createStatement();
> ResultSet rs=stmt.executeQuery(query);
> if(!(rs.next())){
> errorstring+=" No results returned <br>";
> }
> userdbid=rs.getInt("ID");
> }catch(SQLException e){
> errorstring+=" SQLException Getting DB User ID:"+e+"<br>";
> errorstring+=" Query Performed: "+query+"<br>";
> }
> try{
> Statement stmt=conn.createStatement();
> query="select * from passwords where id='"+userdbid+"'";
> ResultSet rs=stmt.executeQuery(query);
> rs.next();
> password=rs.getString("password");
> //out.print("Retrieved Password: "+password+"<br>");
> //out.print("Sent Password: "+pwd+"<br>");
> }catch(SQLException e){errorstring+=" SQLException Getting
> password:"+e+"<br>";}
> if(pwd.equalsIgnoreCase(password))
> return true;
> else
> return false;
> }
>
>
> /** This method builds the security token based on the information
> in the
> database relating to the userdbid value. */
>
> private SecurityToken buildtoken(Connection con)
> {
> String sql;
> SecurityToken st=new SecurityToken();
> try{
> Statement stmt=con.createStatement();
> sql="select * from security where user_id='"+userdbid+"'";
> ResultSet rs=stmt.executeQuery(sql);
> while(rs.next())
> {
> st.addRight(new
> BOARight(rs.getString("app_name"),rs.getInt("level")));
> }
> }catch(SQLException e){errorstring+=" SQLException building
> token:"+e+"<br>";}
> return st;
>
> }
>
> /** This method builds the person object based on the information
> in the
> database relating to the userdbid value. */
>
> private person buildperson(Connection con)
> {
> person tempperson=new person();
> try{
> Statement stmt=con.createStatement();
> String sql="select * from users where id='"+userdbid+"'";
> ResultSet rs=stmt.executeQuery(sql);
> rs.next();
> tempperson.setid(rs.getString("id"));
> tempperson.setfname(rs.getString("firstname"));
> tempperson.setlname(rs.getString("lastname"));
> tempperson.setdivision(rs.getString("udivision"));
> tempperson.setsection(rs.getString("usection"));
> tempperson.setunit(rs.getString("uunit"));
> }catch(SQLException e){errorstring+=" SQLException building
> person. ";}
> return tempperson;
> }
>
>
> /** Processes requests for both HTTP <code>GET</code> and
> <code>POST</code> methods.
> * @param request servlet request
> * @param response servlet response
> */
> protected void processRequest(HttpServletRequest request,
> HttpServletResponse response)
> throws ServletException, java.io.IOException {
> success=false;
> errorstring="";
> String forward=(String)request.getAttribute("forward");
> HttpSession session=request.getSession();
> if(forward==null)
> {
> forward=(String) session.getAttribute("forward");
> if(forward==null)
> {
> forward="/debug1.jsp";
>
> }
> }
> conn=pool.getConnection();
> //response.setContentType("text/html");
> //java.io.PrintWriter out = response.getWriter();
> String[] temparray=request.getParameterValues("userid");
> String[] temparray2=request.getParameterValues("password");
> if((temparray==null)||(temparray2==null))
> {
> errorstring="Sorry, you didn't supply a userid or password.";
> request.setAttribute("error",errorstring);
> request.setAttribute("forward",forward);
> RequestDispatcher
> rd=getServletContext().getRequestDispatcher("/login.jsp");
> rd.forward(request,response);
> //out.print("Forward: "+forward);
> }
> else
> {
> String userid=temparray[0];
> String password=temparray2[0];
> if(authenticate(conn,userid,password))
> {
> success=true;
> SecurityToken st=buildtoken(conn);
> person user=buildperson(conn);
> request.getSession().setAttribute("security",st);
> request.getSession().setAttribute("person",user);
>
> }
>
> }
>
>
> //out.print("Errors: "+errorstring+"<br>");
> //out.print("Userid: "+userid+"<br>");
> // out.print("Password: "+password+"<br>");
> //out.print("Userdb ID:"+userdbid+"<br>");
> //out.print("Authentication: "+success+"<br>");
> //out.print("Forward: "+forward+"<br>");
> //out.close();
> request.setAttribute("error",errorstring);
> RequestDispatcher
> rd=getServletContext().getRequestDispatcher(forward);
> rd.forward(request,response);
>
>
> }
>
> /** Handles the HTTP <code>GET</code> method.
> * @param request servlet request
> * @param response servlet response
> */
> protected void doGet(HttpServletRequest request,
> HttpServletResponse response)
> throws ServletException, java.io.IOException {
> processRequest(request, response);
> }
>
>
>
>
>
>
>
> /** Handles the HTTP <code>POST</code> method.
> * @param request servlet request
> * @param response servlet response
> */
> protected void doPost(HttpServletRequest request,
> HttpServletResponse response)
> throws ServletException, java.io.IOException {
> processRequest(request, response);
> }
>
> /** Returns a short description of the servlet.
> */
> public String getServletInfo() {
> return "Servlet for authenticating to BOA webapps";
> }
>
> }
>
>
> &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
>
> End of source code
>
> &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
>
>
> Here's the stack trace that the servlet dumps:
>
> java.lang.IllegalStateException: Cannot forward after response has been
> committed
> at
> org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:368)
> at
> org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:356)
> at boa.BOAAuthenticate.processRequest(BOAAuthenticate.java:185)
> at boa.BOAAuthenticate.doGet(BOAAuthenticate.java:196)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
> at
> org.apache.catalina.servlets.InvokerServlet.serveRequest(InvokerServlet.java:466)
> at
> org.apache.catalina.servlets.InvokerServlet.doGet(InvokerServlet.java:180)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
> at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
> at
> org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
> at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
> at
> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
> at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
> at
> org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
> at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
> at
> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
> at
> org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
> at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
> at
> org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
> at
> org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
> at
> org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
> at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
> at
> org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
> at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
> at
> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
> at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
> at
> org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
> at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
> at
> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
> at
> org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
> at
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:594)
> at
> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:392)
> at
> org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:565)
> at
> org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:619)
> at java.lang.Thread.run(Thread.java:536
>
>
> &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
>
> End of stack trace
>
> &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
>
> I'm am currently maping servlets for this application to the "invoker"
> via the web.xml. I'm doing this to make them work again and I haven't
> seen anyone list any alternatives.
>
> Thanks ahead of time for anyone that has any insight.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org