java.lang.IllegalStateException: STREAM
at org.eclipse.jetty.server.Response.getWriter(Response.java:707)
java.lang.IllegalStateException: WRITER
at org.eclipse.jetty.server.Response.getOutputStream(Response.java:681)
今天在写一个框架的时候遇到一个问题,记录一下,报错如上,查看javax.servlet.ServletResponse接口中的定义如下:
/**
* Returns a {@link ServletOutputStream} suitable for writing binary
* data in the response. The servlet container does not encode the
* binary data.
* <p> Calling flush() on the ServletOutputStream commits the response.
* Either this method or {@link #getWriter} may
* be called to write the body, not both.
*
* @return a {@link ServletOutputStream} for writing binary data
*
* @exception IllegalStateException if the <code>getWriter</code> method
* has been called on this response
*
* @exception IOException if an input or output exception occurred
*
* @see #getWriter
*
*/
public ServletOutputStream getOutputStream() throws IOException;
/**
* Returns a <code>PrintWriter</code> object that
* can send character text to the client.
* The <code>PrintWriter</code> uses the character
* encoding returned by {@link #getCharacterEncoding}.
* If the response's character encoding has not been
* specified as described in <code>getCharacterEncoding</code>
* (i.e., the method just returns the default value
* <code>ISO-8859-1</code>), <code>getWriter</code>
* updates it to <code>ISO-8859-1</code>.
* <p>Calling flush() on the <code>PrintWriter</code>
* commits the response.
* <p>Either this method or {@link #getOutputStream} may be called
* to write the body, not both.
*
*
* @return a <code>PrintWriter</code> object that
* can return character data to the client
*
* @exception UnsupportedEncodingException
* if the character encoding returned
* by <code>getCharacterEncoding</code> cannot be used
*
* @exception IllegalStateException
* if the <code>getOutputStream</code>
* method has already been called for this
* response object
*
* @exception IOException
* if an input or output exception occurred
*
* @see #getOutputStream
* @see #setCharacterEncoding
*
*/
public PrintWriter getWriter() throws IOException;
注意这两句:
Either this method or {@link #getWriter} may be called to write the body, not both.
Either this method or {@link #getOutputStream} may be called to write the body, not both.
再看jetty的源码,jetty.server.Response的源码:
public ServletOutputStream getOutputStream() throws IOException
{
if (_outputState!=NONE && _outputState!=STREAM)
throw new IllegalStateException("WRITER");
ServletOutputStream out = _connection.getOutputStream();
_outputState=STREAM;
return out;
}
public PrintWriter getWriter() throws IOException
{
if (_outputState!=NONE && _outputState!=WRITER)
throw new IllegalStateException("STREAM");
/* if there is no writer yet */
if (_writer==null)
{
/* get encoding from Content-Type header */
String encoding = _characterEncoding;
if (encoding==null)
{
/* implementation of educated defaults */
if(_cachedMimeType != null)
encoding = MimeTypes.getCharsetFromContentType(_cachedMimeType);
if (encoding==null)
encoding = StringUtil.__ISO_8859_1;
setCharacterEncoding(encoding);
}
/* construct Writer using correct encoding */
_writer = _connection.getPrintWriter(encoding);
}
_outputState=WRITER;
return _writer;
}
从源码的第3-4行可以得以验证,也就是说对于同一个response实例你只能使用其中的一个方法,不能两者混用。