Exception occurred when flushing data . What is th

2019-01-26 21:09发布

问题:

There is something interesting going on. When I call a url abc.com a servlet is addressed but the request passes through a filter (to the servlet). From the servlet I try to dispatch the request to a jsp page.But as I try to dispatch the request I get an exception thrown which is : java.lang.IllegalStateException: Exception occurred when flushing data

Filter code

public class FirstSiteFilter implements Filter {
private FilterConfig fc;

@Override
public void init(FilterConfig config) throws ServletException {
    this.fc = config;
}

@Override
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) 
        throws ServletException,IOException {
    String IP = request.getRemoteAddr();
    request.setAttribute("client IP from the filter", IP);
    chain.doFilter(request, response);
}

@Override
public void destroy() {

}   
}

Servlet code (request is chained to this servlet from the filter)

public class FW_FirstSite extends HttpServlet {


@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    String IP = (String)request.getAttribute("client IP from the filter");
    request.setAttribute("Client IP", IP);
    // THE FOLLOWING TWO STATEMENTS CAUSE AN EXCEPTION
    // IF I COMMENT THEM OUT NO EXCEPTION IS THROWN BUT AN EXCEPTION IS THROWN IF I LEAVE THEM AS IT IS
    RequestDispatcher rd = request.getRequestDispatcher("index.jsp");
    rd.forward(request,response);
}
}

Why is it that I get an exception of this type ? If instead I put the statement response.sendRedirect("...") after the statement request.setAttribute("client IP",IP) it works.

EDIT (web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
    <servlet-name>guestbook</servlet-name>
    <servlet-class>guestbook.GuestbookServlet</servlet-class>
</servlet>
<servlet>
    <servlet-name>emailtest</servlet-name>
    <servlet-class>Servlets.emailtest</servlet-class>
</servlet>
<servlet>
    <servlet-name>ValidateCredentials</servlet-name>
    <servlet-class>Servlets.ValidateCredentials</servlet-class>
</servlet>
<servlet>
    <servlet-name>UploadImagesToAisle</servlet-name>
    <servlet-class>Servlets.UploadImagesToAisle</servlet-class>
</servlet>
<servlet>
    <servlet-name>HandleSongLink</servlet-name>
    <servlet-class>Servlets.HandleSongLink</servlet-class>
</servlet>
<servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>Servlets.context</servlet-class>
</servlet>
<servlet>
    <servlet-name>HandleVideoLink</servlet-name>
    <servlet-class>Servlets.HandleVideoLink</servlet-class>
</servlet>
<servlet>
    <servlet-name>HandlePoetry</servlet-name>
    <servlet-class>Servlets.HandlePoetry</servlet-class>
</servlet>
<servlet>
    <servlet-name>displaykey</servlet-name>
    <servlet-class>Servlets.displaykey</servlet-class>
</servlet>
<servlet>
    <servlet-name>tester_writeXML</servlet-name>
    <servlet-class>Servlets.tester_writeXML</servlet-class>
</servlet>
<servlet>
    <servlet-name>ShowBlob</servlet-name>
    <servlet-class>Servlets.ShowBlob</servlet-class>
</servlet>
<servlet>
    <servlet-name>FW_FirstSite</servlet-name>
    <servlet-class>Servlets.FW_FirstSite</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>guestbook</servlet-name>
    <url-pattern>/guestbook</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>sign</servlet-name>
    <servlet-class>guestbook.SignGuestbookServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>sign</servlet-name>
    <url-pattern>/sign</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>HandleSubmittedPoem</servlet-name>
    <servlet-class>Servlets.HandleSubmittedPoem</servlet-class>
</servlet>
<servlet>
    <servlet-name>HandleSubmittedMessage</servlet-name>
    <servlet-class>Servlets.HandleSubmittedMessage</servlet-class>
</servlet>
<servlet>
    <servlet-name>HandleSongDedicated</servlet-name>
    <servlet-class>Servlets.HandleSongDedicated</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HandleSubmittedPoem</servlet-name>
    <url-pattern>/HandleSubmittedPoem</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>HandleSubmittedMessage</servlet-name>
    <url-pattern>/HandleSubmittedMessage</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>HandleSongDedicated</servlet-name>
    <url-pattern>/HandleSongDedicated</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>emailtest</servlet-name>
    <url-pattern>/emailtest</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>ValidateCredentials</servlet-name>
    <url-pattern>/ValidateCredentials</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>UploadImagesToAisle</servlet-name>
    <url-pattern>/UploadImagesToAisle</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>HandleSongLink</servlet-name>
    <url-pattern>/HandleSongLink</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>context</servlet-name>
    <url-pattern>/context</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>HandleVideoLink</servlet-name>
    <url-pattern>/HandleVideoLink</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>HandlePoetry</servlet-name>
    <url-pattern>/HandlePoetry</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>displaykey</servlet-name>
    <url-pattern>/displaykey</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>tester_writeXML</servlet-name>
    <url-pattern>/tester_writeXML</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>ShowBlob</servlet-name>
    <url-pattern>/ShowBlob</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>FW_FirstSite</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>FirstSiteFilter</filter-name>
    <filter-class>Filters.FirstSiteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>FirstSiteFilter</filter-name>
    <servlet-name>FW_FirstSite</servlet-name>
</filter-mapping>



<!--
<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
-->

</web-app>

回答1:

RequestDispatcher always needs a forward slash. So try changing it to the following

RequestDispatcher rd = request.getRequestDispatcher("/index.jsp");

When you use RequestDispatcher.forward to call another servlet, it is "chain of command."

When a servlet is first called, the response object is fresh and new: its headers have not been set, its buffers are empty, and no data has been written to the client.

However, as soon as either the status code or any of the headers have been written -- or potentially written -- to the client, or when data has been -- or may have been -- written to the body stream, then you may be susceptible to the IllegalStateException error. The problem that this exception is signalling is the new data that you are (or may be) writing is inconsistent with the data that's already been set and then irretrivably sent ("committed") to the client.

Two common variants of this exception are "java.lang.IllegalStateException: Header already sent" and "java.lang.IllegalStateException: Cannot forward as Output Stream or Writer has already been obtained".

"Header already sent" means that one or more headers have been committed to the client, so you can't set that header again.

"Output Stream or Writer has already been obtained" means that since the calling servlet has already called response.getWriter() or response.getOutputStream(), that contaminates the data stream, since the response has been (or may have been) written to already, making it unsuitable for forwarding.