❌ No, you cannot use both PrintWriter
and ServletOutputStream
simultaneously in a servlet for the same response.
It is forbidden by the Servlet specification.
Mixing them causes IllegalStateException
.
🧠 Why?
- The response can either be character-based (
PrintWriter
) or byte-based (ServletOutputStream
). - Not both.
- Once you get one, the underlying response output handling is set (to either character encoding mode or binary mode).
- Mixing would break the HTTP response stream.
⚡ Example of what NOT to do:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter writer = response.getWriter();
ServletOutputStream outputStream = response.getOutputStream(); // ❌ WRONG!
}
✅ As soon as you call response.getWriter()
, trying to call response.getOutputStream()
will throw an exception at runtime.
Or vice versa.
🎯 Servlet Specification (Official) says:
If
getWriter()
has been called, then callinggetOutputStream()
must throw anIllegalStateException
, and vice versa.
🚀 How to decide which one to use?
Situation | Use |
---|---|
You send text (HTML, JSON, plain text) | PrintWriter |
You send binary data (images, PDFs, zip files) | ServletOutputStream |
✅ Always pick one early when building the response, depending on what you’re sending.
🛠️ Correct usage examples
✅ Use only PrintWriter:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<h1>Hello World!</h1>");
}
✅ Use only ServletOutputStream:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/octet-stream");
ServletOutputStream out = response.getOutputStream();
out.write(new byte[]{1, 2, 3, 4});
}
🔥 Super Quick Summary:
PrintWriter | ServletOutputStream | |
---|---|---|
Type | Character stream | Byte stream |
getWriter() locks response into | Character mode | |
getOutputStream() locks response into | Binary mode | |
Use both together? | ❌ NO, IllegalStateException |