Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This noncompliant code example shows an example where ..illustrates a servlet that indicates if an internal error occurs by using the HttpServletResponse.sendError() method to indicate an internal server error.

Code Block
bgColor#ffcccc
languagejava
public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException, ServletException {

  PrintWriter out = response.getWriter();
  try {
    out.println("<html>");

    // ... write some response text

    out.flush();  // commits the stream

    // ... more work

  } catch (IOException x) {
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  }
}

If an IOException occurs after flushing the stream, the stream will be committed when the catch clause executes. Consequently, the sendError() operation will throw an IllegalStateException.

Noncompliant Code Example

This noncompliant code example illustrates a servlet that indicates if an internal error occurs by printing an error message to the output stream and flushing it.

Code Block
bgColor#ffcccc#FFCCCC
 

 

Compliant Solution

In this compliant solution, ...

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

  PrintWriter out = response.getWriter();
  try {
    out.println("<html>");

    // ... write some response text

    out.flush();  // commits the stream

    // ... more work

  } catch (IOException x) {
    out.println(x.getMessage());
    out.flush();
  }
}

If an IOException occurs after flushing the stream, the stream will be re-flushed in the catch clause.

Compliant Solution

The sendError() method should only be used before an output stream or writer has been created, as it overwrites any output. Once the output stream or writer has been created, errors should be output alongside valid HTML. This compliant solution uses both strategies, ensuring that the stream is flushed only once, in the finally clause.

Code Block
bgColor#ccccff
languagejava
public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException, ServletException {

  try {
    // do work that doesn't require the output writer
  } catch (IOException x) {
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  }

  PrintWriter out = response.getWriter();
  try {
    out.println("<html>");

    // ... all work

  } catch (IOException ex) {
    out.println(ex.getMessage());
  } finally {
    out.flush();
  }
}
Code Block
bgColor#CCCCFF
 

Risk Assessment

If a servlet's output stream is reset after it has been committed, an IllegalStateException usually results, which can cause the servlet's response to be truncated.

...